Rails 4 Custom HABTM Validation for Associations

I have a simple script, but I cannot find any suggested solutions related to Rails 4. I just want to add a special validator that checks the number of stored associations between my HABTM association. Easier said and done, to my surprise?

I was looking for a solution, but I get answers only to earlier versions of Rails. I have the following:

class User < ActiveRecord::Base

  has_and_belongs_to_many :roles
  after_save :check_maximum_number_of_roles

  .
  .
  .

  private

  def check_maximum_number_of_roles
    if self.roles.length > 3
      errors.add(:roles, 'Users can only have three roles assigned.')
      return false
    end
  end

end

class Role < ActiveRecord::Base

  has_and_belongs_to_many :users

end

The reason I use after_saveis because, as I understand it, a saved association is first available after adding it. I also tried to write a special validator (for example, validate: :can_only_have_one_role), but this also does not work.

I add the association as follows and do it in the rails console (what should work fine?):

user.roles << role

, - .

, !

+4
1

user.roles << role user. . .

, , : has_and_belongs_to_many, . Rails has_many :through, " " .

, (, , ) has_many/belongs_to. " " Rails. :

class Role
  has_many :users
end

class User
  belongs_to :role
end

, , , UserRole, has_many :through UserRole.

class User
  has_many :user_roles
  has_many :roles, through: :user_roles
end

class UserRole
  belongs_to :user
  belongs_to :role

  # Validate that only one role exists for each user
  validates :user_id, uniqueness: { scope: :role_id }

  # OR, to validate at most X roles are assigned to a user
  validate :at_most_3_roles, on: :create

  def at_most_3_roles
    duplicates = UserRole.where(user_id: user_id, role_id: role_id).where('id != ?', id)
    if duplicates.count > 3
      errors.add(:base, 'A user may have at most three roles')
    end
  end
end

class Role
  has_many :user_roles
  has_many :users, through: :user_roles
end
+7

Source: https://habr.com/ru/post/1547044/


All Articles