ruby-on-rails - rails 4 : Difference between validates presence on id or association

标签 ruby-on-rails validation ruby-on-rails-4 model-associations

如果我在模型中有一个“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 )由于 pancake 缺少验证错误而失败。)

最佳答案

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

将返回错误。然而:
topping.pancake_id = -12
topping.valid?

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

继续我的问题,进一步调查显示 blank?代表empty? ,确实有人定义了empty?在煎饼上,如果没有浇头则返回真。

找到了罪魁祸首,并且学到了一些关于 Rails 的东西。

关于ruby-on-rails - rails 4 : Difference between validates presence on id or association,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29012252/

相关文章:

ruby-on-rails - 使用 bootstrap_form gem 时出现问题 - 找不到文件 'rails_bootstrap_forms' 错误

ruby-on-rails - ActiveRecord::EagerLoadPolymorphicError: 无法立即加载多态关联

java - JSF 中电话号码的自定义 validator

ruby-on-rails - 我们如何在其他 Controller View 中使用一个 Controller 方法?

ruby-on-rails - 测试旧版 Rails 应用程序 : circular argument reference warning, 无法加载测试/单元/断言

ruby-on-rails - 禁用第一个 nil 选项 - rails

ruby-on-rails - 在 Ubuntu/Monit 中将 Mailman 脚本作为服务运行

ruby-on-rails - 在 Windows 7 x64 上安装 Ruby and Rails 和 DevKit 时出现问题 - 需要修复

validation - Mongoose 需要 Array

validation - 在express/connect中重新填充表单值