使用Rails 3.2,不确定是否会产生影响
Owner
has_many
Bicycles
我想根据Bicycles
模型上Owner
字段的值,限制bicycle_limit
可以拥有的Owner
个数存储该所有者的允许限制。
目前,我希望limit_bicycle_ownership
验证能够在验证/保存Bicycle
或Owner
时运行(我稍后会限制它)。为此,我已将validates_associated: :owner
放在Bicycle
模型上。
class Owner < ActiveRecord::Base
has_many :bicycles, inverse_of: :owner
validate :limit_bicycle_ownership
def limit_bicycle_ownership
if bicycles(:reload).size > bicycle_limit
errors.add(:bicycles, "^Too many bicycles")
end
end
end
class Bicycle < ActiveRecord::Base
belongs_to :owner, inverse_of: :bicycles
validates_presence :owner
validates_associated: :owner
end
当使用以下方式通过Owner
模型的实例设置或更改自行车的所有权时,此设置的行为与预期相同:
owner = Owner.create(bicycle_limit: 1)
owner.bicycles << Bicycle.create()
owner.valid? # true
owner.bicycles << Bicycle.create()
owner.valid? # false
但是,当通过Bicycle
模型的实例更改所有权时,验证似乎不起作用:
owner = Owner.create(bicycle_limit: 1)
bicycle1 = Bicycle.new(owner_id: owner.id)
bicycle1.valid? # true
owner.valid? # true
bicycle1.save! # true
bicycle2 = Bicycle.new(owner_id: owner.id)
bicycle2.valid? # true
owner.valid? # true
bicycle2.save! # true, but I was expecting this to fail
owner.valid? # false
我已经撬开了limit_bicycle_ownership
验证,据我所知,这是自行车2的过程!运行:
bicycle2
了解与owner
的新关联,以通过validates_association :owner
回调验证owner
但是,似乎没有任何关于现在导致其验证的关联的知识,并且bicycles(:reload)
仅返回与bicycle1
的现有关联owner
上的验证然后通过,因为就owner
而言,它只拥有一个自行车(bicycle1
),但不超过它bicycle_limit
的1 bicycle2
然后继续验证并保存,并成功保存,让owner
拥有两辆自行车所以基本上在设置或更新自行车的拥有者时,其新主人甚至不知道自行车是否存在,直到自行车完成保存,此时执行validates_associated
呼叫为时已晚。有关更好的方法的任何想法,而不必复制Owner
模型中Bicycle
模型的验证逻辑?我觉得可能有一个解决方案涉及after_save
模型上的Bicycle
回调,但我真的不知道从哪里开始。
答案 0 :(得分:0)
我认为你可以在自行车添加到所有者时启动交易,如果添加所有者后无效则回滚:
Bicycle.transaction do
bicycle2 = Bicycle.new(owner_id: owner.id)
bicycle2.valid? # true
owner.valid? # true
bicycle2.save!
if !owner.valid?
raise ActiveRecord::Rollback, "Error message..."
end
end