Confirm the maximum amount of related objects

I have an account model and a user model:

class Account < ActiveRecord::Base has_many :users end class User < ActiveRecord::Base belongs_to :account end 

Users belong to the account, and the account has a maximum user size (for each account - different). But how can I confirm that this maximum was not reached when adding new users to the account?

First I tried to add user validation:

 class User < ActiveRecord::Base belongs_to :account validate :validate_max_users_have_not_been_reached def validate_max_users_have_not_been_reached return unless account_id_changed? # nothing to validate errors.add_to_base("can not be added to this account since its user maximum have been reached") unless account.users.count < account.maximum_amount_of_users end end 

But this only works if I add one user at a time.

If I add multiple users via @account.update_attributes(:users_attributes => ...) , it just goes straight ahead, even if there is only room for another user.

Update:

Just to clarify: the current verification method confirms that account.users.count less than account.maximum_amount_of_users . For example, let's say that account.users.count is 9 and account.maximum_amount_of_users is 10, then the check will pass because 9 <10.

The problem is that the counter returned from account.users.count will not increase until all users are written to the database. This means that adding multiple users at the same time will be tested, as the user counter will be the same until all of them are verified.

So, as yggggy points out, should I add confirmation to my account model? And how should this be done?

+6
validation ruby-on-rails activerecord
source share
2 answers

If you call account.users.size instead of account.users.count , it will also include users who were created but not saved in the database.

HOWEVER , this will not completely solve your problem. When you call account on a user, it does not return the same instance of the account that @account points @account , so it does not know about new users. I believe this will be “fixed” in Rails 3, but for now I can come up with a couple of solutions.

If you save the account at the same time as adding users (which I assume, since you are calling update_attributes ), then verification can go there.

 # in account.rb def validate_max_users_have_not_been_reached errors.add_to_base("You cannot have more than #{maximum_amount_of_users} users on this account.") unless users.size < maximum_amount_of_users end 

I'm not sure how you save the related models, but if the account verification fails, they should not be saved.

Another solution is to reset the user.account instance for itself when updating user attributes. You can do this in the set users_attributes method.

 # in account.rb def users_attributes=(attributes) #... user.account = self #... end 

Thus, the user account will point to the same instance of the account so that account.users.size should return the amount. In this case, you save the checks in the user model.

This is a difficult problem, but hopefully it has given you some ideas on how to solve it.

+16
source share

The reason it passes is because update_attributes does not pass validation.

In addition, your logic only checks the existing number of accounts for the maximum allowed. There is no calculation given the number of users trying to add. I would think that this logic is more relevant to the Account (?) Model.

-2
source share

All Articles