Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 验证关联对象的最大数量_Ruby On Rails_Validation_Activerecord - Fatal编程技术网

Ruby on rails 验证关联对象的最大数量

Ruby on rails 验证关联对象的最大数量,ruby-on-rails,validation,activerecord,Ruby On Rails,Validation,Activerecord,我有一个帐户模型和一个用户模型: class Account < ActiveRecord::Base has_many :users end class User < ActiveRecord::Base belongs_to :account end 类帐户

我有一个帐户模型和一个用户模型:

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
class用户
但这只有在每次添加一个用户时才有效

如果我通过
@account.update\u attributes(:users\u attributes=>…)
添加多个用户,即使只有一个用户的空间,它也会直接通过

更新:

只是澄清一下:当前的验证方法验证
account.users.count
是否小于
account.max\u amount\u用户
。比如说,
account.users.count
是9,而
account.u用户的最大金额是10,那么验证将通过,因为9<10

问题是,在将所有用户写入数据库之前,从account.users.count返回的计数不会增加。这意味着同时添加多个用户将通过验证,因为在所有用户都经过验证之前,用户计数将是相同的


正如askegg指出的,我是否也应该向帐户模型添加验证?那么应该如何做呢?

它传递的原因是更新属性没有经过验证


另外-您的逻辑仅根据允许的最大帐户数检查现有帐户数。考虑到试图添加的用户数量,没有计算。如果调用
Account.users.size
而不是
Account.users.count
,我认为这种逻辑更适合于帐户模型(?)。

它还将包括已生成但未保存到数据库中的用户

但是这并不能完全解决您的问题。在用户中调用
@account
时,它不会返回
@account
指向的同一帐户实例,因此它不知道新用户的情况。我相信这在Rails3中是“固定”的,但同时我可以想出一些解决方案

如果您在添加用户的同时保存帐户(我假设是这样,因为您正在调用
update\u 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
这样,用户的帐户将指向同一帐户实例,因此
account.users.size
应返回金额。在这种情况下,您将在用户模型中保留验证


这是一个棘手的问题,但希望这能为您提供一些解决方法。

update\u属性会运行验证,至少在Rails 2.3.2中是这样。但问题是,用户模型上的验证方法验证了与帐户上已有的用户数量相比,没有达到最大值。也就是说,如果max==10,users.count==9,那么-当同时添加两个用户时-将对这两个用户运行验证,但每次验证9<10。因为在将用户写入数据库之前,users.count不会增加。但如何在客户模型上验证这一点呢?我是否应该覆盖更新属性等?啊-对不起。Update_属性(注意末尾缺少的“s”)绕过验证。我的错误。看起来Ryan(比我有更多的Rubyfoo)已经回答了你的问题。我不知道“size”方法包括未保存的记录。您每天都会学到一些东西:)在一个高吞吐量的应用程序上,如何在数据库(postgres)上做到这一点?
# in account.rb
def users_attributes=(attributes)
  #...
  user.account = self
  #...
end