Rails 4:验证id或关联的存在之间的区别

A F*_*kly 10 validation ruby-on-rails model-associations ruby-on-rails-4

如果我在模型中有'belongs_to'关联,我想知道验证关联之间的名义差异:

  class Topping  < ActiveRecord::Base
    belongs_to :pancake
    validates  :pancake, presence: true
    ...
Run Code Online (Sandbox Code Playgroud)

并验证关联的模型ID:

  class Topping  < ActiveRecord::Base
    belongs_to :pancake
    validates  :pancake_id, presence: true
    ...
Run Code Online (Sandbox Code Playgroud)

动机:

为煎饼分配顶部的一些代码在过去的某个时间停止了工作.将验证从关联更改为id'修复'问题,但我想知道更深层次的原因.

(仅供参考,当进入代码时,煎饼有效并且在数据库中,并且顶部响应两者.pancake并且.pancake_id相应.推送操作符(pancake.toppings << topping)和手动分配以及save(topping.pancake = pancake; topping.save)都失败,并且煎饼缺少验证错误.)

A F*_*kly 6

进一步调查,我发现“存在”验证器解析为“add_on_blank”:

http://apidock.com/rails/ActiveModel/Errors/add_on_blank

def add_on_blank(attributes, options = {})
  Array(attributes).each do |attribute|
    value = @base.send(:read_attribute_for_validation, attribute)
    add(attribute, :blank, options) if value.blank?
  end
end
Run Code Online (Sandbox Code Playgroud)

这就是它所说的:如果有问题的属性是,则会添加验证错误blank?

这意味着这只是一个存在性检查。因此,如果我验证一个 id,则该 id 必须存在。这意味着:

topping.pancake = Pancake.new
topping.valid?
Run Code Online (Sandbox Code Playgroud)

会返回 false。然而:

topping.pancake_id = -12
topping.valid?
Run Code Online (Sandbox Code Playgroud)

会返回true。另一方面,如果我验证该对象,则情况恰恰相反。除非 -12 是一个有效的索引,在这种情况下,ActiveRecord 会在收到“pancake”消息时自动从数据库加载它。

继续我的问题,进一步的调查表明,blank?代表们empty?,而且确实有人empty?在煎饼上定义了,如果没有配料,则返回 true。

找到了罪魁祸首,并学到了一些有关 Rails 的知识。