You had two problems:
- You override validations
- The order of operations when saving causes problems.
You are rewriting a validation method, which is bad because the built-in behavior prohibits entries with validation errors that must be stored in the database. To add custom checks, you want to do this:
validate :maximum_group_length def maximum_group_length if self.groups.length > 5 self.errors.add(:groups, "cannot have more than 5 groups") end end
However, the nature of the HABTM relationship requires you to do this as an after_save callback. Just because everything is done. user.groups based on an implicit connection table, and there it is not updated for it until the connection table is updated.
If you try to check as part of a callback (before_save, after_creation, etc.), then adding an error to the object will not result in a rollback. Callbacks will only rollback if they return false. This question will be considered after implementation after saving the question.
after_save :validate_maximum_group_length def validate_maximum_group_length if self.groups.length > 5 self.errors.add(:groups, "cannot have more than 5 groups") return false end end
Another solution is to use an explicit join model. And has_many: through relationships. The connection model table is updated in the update instruction. Where, when has_many: through and HABTM relationships update relationships after saving.
class User < ActiveRecord::Base has_many :user_groups has_many :groups, :through => user_groups, allow_destroy validate :max_group_length errors.add(:groups, "cannot have more than 5 groups") if self.user_groups.length > 5 end end class UserGroup < ActiveRecord::Base belongs_to :user belongs_to :group end class Group < ActiveRecord::Base has_and_belongs_to_many :users end
HABTM implicitly uses the connection table, so it does not need to be changed on the group side.
However, you will need to change your form to update the form to provide group_id in the params hash as params[:user][:user_group_attributes][0][:group_id][3]