如果我在模型中具有“belongs_to”关联,那么我想知道验证关联之间的概念差异:

  class Topping  < ActiveRecord::Base
    belongs_to :pancake
    validates  :pancake, presence: true
    ...

并验证关联的模型ID:
  class Topping  < ActiveRecord::Base
    belongs_to :pancake
    validates  :pancake_id, presence: true
    ...

动机:

在过去的某个时候,一些为薄煎饼分配了馅料的代码停止了工作。将验证从关联更改为id可以“解决”问题,但我想知道更深层的原因。

(仅供引用,当进入代码时,煎饼是有效的,并且在数据库中,并且馅料适本地响应了.pancake.pancake_id。推送运算符(pancake.toppings << topping)以及手动分配和保存(topping.pancake = pancake; topping.save)均失败,并且煎饼缺少验证错误。 )

最佳答案

进一步调查,我发现“状态”验证器解析为“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

这样做的含义是:如果有问题的属性为blank?,则添加验证错误

这意味着它只是存在检查。因此,如果我验证一个ID,则该ID必须存在。这意味着:
topping.pancake = Pancake.new
topping.valid?

会返回false。然而:
topping.pancake_id = -12
topping.valid?

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

继续研究我的问题,进一步的调查表明blank?委托(delegate)给empty?,的确有人在煎饼上定义了empty?,如果没有浇头则返回true。

找到了罪魁祸首,并从Rails中学到了一些东西。

10-08 04:21