我有一个帐户模型和一个用户模型:
class Account < ActiveRecord::Base
has_many :users
end
class User < ActiveRecord::Base
belongs_to :account
end
用户属于某个帐户,并且帐户具有最大用户(每个帐户不同)。但是,如何在向帐户添加新用户时验证是否未达到此最大值?
首先,我尝试在用户上添加验证:
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
但这只有在我一次添加一个用户时才有效。
如果我通过@account.update_attributes(:users_attributes => ...)
添加多个用户,即使只有一个用户的空间,它也会直接通过。
更新
只是为了澄清:当前的验证方法验证account.users.count
小于account.maximum_amount_of_users
。例如,假设account.users.count
为9且account.maximum_amount_of_users
为10,则验证将通过,因为9&lt; 10。
问题是从account.users.count
返回的计数在所有用户都写入数据库之前不会增加。这意味着同时添加多个用户将通过验证,因为用户计数将一直相同,直到它们全部经过验证。
因此,当 askegg 指出时,我是否应该在帐户模型中添加验证?那应该怎么做?
答案 0 :(得分:16)
如果您拨打account.users.size
而不是account.users.count
,它还会包含已构建但未保存到数据库的用户。
但这不能完全解决您的问题。当您在用户中呼叫account
时,它不会返回@account
指向的同一帐户实例,因此它不知道新用户。我相信这将在Rails 3中“修复”,但与此同时我可以想到几个解决方案。
如果您在添加用户的同时保存帐户(我假设您正在调用update_attributes
),那么验证就可以进入。
# 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
我不确定您是如何保存关联模型的,但如果帐户验证失败,则不应保存它们。
另一种解决方案是在更新用户属性时将user.account
实例重置为self。您可以在users_attributes setter方法中执行此操作。
# in account.rb
def users_attributes=(attributes)
#...
user.account = self
#...
end
这样,用户的帐户将指向同一个帐户实例,因此account.users.size
应返回金额。在这种情况下,您将在用户模型中保留验证。
这是一个棘手的问题,但希望这能给你一些如何解决它的想法。
答案 1 :(得分:-2)
它传递的原因是因为update_attributes没有通过验证。
此外 - 您的逻辑仅根据允许的最大值检查现有帐户数。考虑到尝试添加的用户数量,没有计算。我认为这个逻辑更多地属于帐户模型(?)。