Ruby on rails 我应该在什么时候验证ActiveRecord关联对象与其id的存在性?
假设我有一个ActiveRecord关联,如:Ruby on rails 我应该在什么时候验证ActiveRecord关联对象与其id的存在性?,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,假设我有一个ActiveRecord关联,如: class City < ActiveRecord::Base belongs_to :state end 我猜它们是一样的,因为: 属于创建方法state和state= state=设置state\u id 但是,我刚刚修复了一个失败的规范,将其更改为检查id而不是对象 这两种验证方法都可以接受吗?如果是这样,您什么时候会使用一个或另一个?验证:state将使用从城市到州(所属对象)的关系以及外键,而验证:state\u id仅使
class City < ActiveRecord::Base
belongs_to :state
end
我猜它们是一样的,因为:
创建方法属于
和state
state=
设置state=
state\u id
这两种验证方法都可以接受吗?如果是这样,您什么时候会使用一个或另一个?
验证:state
将使用从城市到州(所属对象)的关系以及外键,而验证:state\u id
仅使用列state\u id,并查看它是否有任何值
我首选的方法是验证状态
(关系),因为这需要密钥和关系都存在
验证state_id将起作用,因为它将确保state id存在,但是它不会检查代码的有效性,即,对于城市中的任何给定state key,state实际上“存在”
基本上,如果城市中使用的外键(用于state_id)都作为state中的实际记录存在,效果是相同的。如果state中有无效的state代码,则会显示差异 如果你做了类似的事情怎么办
s = State.new
c = City.new
c.state = s
c.valid?
我还没有尝试过这个方法,但是我猜,如果您正在检查c.state_id的存在,它将丢失,即使c确实有一个状态(因为id还没有生成,因为状态还没有保存)
也就是说,如果您关心的是状态的存在,那么您应该验证状态的存在。就我个人而言,我更喜欢让模型更健壮,并接受或。因此,在您的特定情况下,City可以接受
State
对象或State\u id
,但需要发送其中一个
class City < ActiveRecord::Base
attr_accessible :state, :state_id
validates :state, presence: true, if: proc{|c| c.state_id.blank? }
validates :state_id, presence: true, if: proc{|c| c.state.blank? }
belongs_to :state
end
class City
Edit:删除了validate语句中的双负片。最初有除非:proc{c | c |!c.state_id.blank?}
根据:
当您试图确保存在关联时,请传递其
外键属性,而不是关联变量本身
这本书没有解释为什么你应该用这个来代替它
validates :region, :presence => true
但我知道这些家伙知道他们的本事。我们能看看你的原始和固定规格吗?我喜欢你的方法。挑剔:没有必要使用
,除非!空白?
;如果为空?
或除非存在?
都可以。这是非常正确的,我要把存在?
放进去,因为这只是的倒数!空白?
,但我更喜欢的可读性!空白
。但是,如果为空,则执行操作?
在没有双重否定:p的情况下也可以正常工作。这与验证:区域,存在:true
类似,只是它还强制检查数据库中是否存在关联。这样做似乎有点奇怪,因为它不提供内存对象的验证。根据经验,只验证对象并添加外键约束以确保键始终有效更容易。但这一点很好。可能是因为性能原因,因为validates:region每次验证对象时都会从DB加载region,而validates:region\u id不会这样做。
validates :region_id, :presence => true
validate :region_exists
def region_exists
errors.add(:region_id, "does not exist") unless Region.exists?(region_id)
end
validates :region, :presence => true