Find_or_initialize_by(nil)返回最后一条记录

时间:2017-09-19 04:44:10

标签: ruby-on-rails ruby csv ruby-on-rails-5

所以我试图创建一个复杂的(imo)CSV / Excel导入过程,该过程必须为3个独立的模型+关联创建记录,并且在调试此过程的验证时,我偶然发现了一个令人困惑的概念关于传递的属性为 find_or_initialize_by() nil

根据Rails API Docsfind_or_initialize_by()应执行以下操作:

# File activerecord/lib/active_record/relation.rb, line 222
  def find_or_initialize_by(attributes, &block)
    find_by(attributes) || new(attributes, &block)
  end

这让我相信,如果我将属性传递给find_by <{>> nil 或甚至 blank ,那么它应该然后将它移到Model.new(nil),对我来说它会不断返回该模型的最后一条记录。

传递Model.find_by()Model.where().find_or_initializenil, {}, false, ""等方法仍会返回最后一条记录。

我希望它初始化具有new属性的nil记录的原因是它无法验证并向用户抛出并错误地返回该行中输入的数据无效。 (因为这不是标准columns = model attributes类型的导入,我必须通过另一个方法解析传递的列,如果条目的一部分是坏的,应该返回nil ...至少这是最好的我能想到的方式。)

所以任何人都能帮助我理解为什么这不起作用,因为我已经解释过,在这种情况下你的建议可能是什么?

谢谢!

1 个答案:

答案 0 :(得分:2)

  

这让我相信如果我将属性传递给find_by那么   是零或甚至空白它应该移动到Model.new(零),   但是,对我而言,它不断返回该模型的最后一条记录。

不,那不对。 find_by()始终返回第一条记录符合指定条件,在您的情况下没有任何条件,因此会返回第一条记录。

如果条件不匹配,则仅返回

=> Model.find_by(nil)       # empty conditions without column specifying 
=> #<Model:0x00561654201c30
=> Model.find_by(foo: nil)  # empty conditions with column specifying
=> nil

为了使用空属性初始化模型,请使用空条件:

=> Model.where(foo: nil, bar: nil).find_or_initialize