What is the best way to prevent the deletion of the last entry in the has_many collection?

I have two ActiveRecord classes. A simplified view of these classes:

class Account < ActiveRecord::Base
  has_many :user_account_roles
end

class UserAccountRole < ActiveRecord::Base
  belongs_to :account

  # Has a boolean attribute called 'administrator'.
end

What I'm struggling with is that I would like to apply two validation rules to it: * Make sure the last UserAccountRole cannot be deleted. * It is not possible to delete the last UserAccountRole, which is the administrator.

I am really trying to understand the best way to achieve this kind of structural validation. I tried adding the before_remove callback to the association, but I do not like that this should cause an error that should be caught by the controller. I would prefer it to be considered "just another check."

class Account < ActiveRecord::Base
  has_many :user_account_roles, :before_remove => check_remove_role_ok

  def check_remove_relationship_ok(relationship)
    if self.user_account_relationships.size == 1
      errors[:base] << "Cannot remove the last user from this account."
      raise RuntimeError, "Cannot remove the last user from this account."
    end
  end

end

I don't think this matters, but I also use accepts_nested_attributes_for.

+3
2

?

class Account < ActiveRecord::Base
  has_many :user_account_roles

  validate :at_least_one_user_account_role
  validate :at_least_one_administrator_role

  private
  def at_least_one_user_account_role
    if user_account_roles.size < 1
      errors.add_to_base('At least one role must be assigned.')
    end
  end

  def at_least_one_administrator_role
    if user_account_roles.none?(&:administrator?)
      errors.add_to_base('At least one administrator role must be assigned.')
    end
  end
end

, , , , , . , , .

+2

UserAccountRole. UserAccountRole, , .

. UserAccountRole AR-? ? ? , , .

0

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


All Articles