What is the best way of preventing the last record in a has_many collection being removed?

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'd like to be able to apply two validation rules to this: * Ensuring that the last UserAccountRole cannot be removed. * Ensuring that the last UserAccountRole that is an administrator cannot be removed.

I'm really struggling to understand the best way of achieving this kind of structural validation. I've tried adding a before_remove callback to the association, but I don't like that this has to throw an error which would need to be caught by the controller. I'd rather this be treated as 'just another validation'.

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 makes any difference, but I'm also using accepts_nested_attributes_for.

Answers


Why not use a simple validation on Account?

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

This way nothing needs to be raised, and the record won't be saved unless there's at least one role, and at least one administrator role. Thus when you re-render your edit form on error, this message will show up.


Need Your Help

Comparing IEEE floats and doubles for equality

variables floating-point inequality

What is the best method for comparing IEEE floats and doubles for equality? I have heard of several methods, but I wanted to see what the community thought.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.