【问题标题】:Find_or_initialize_by(nil) returns last recordFind_or_initialize_by(nil) 返回最后一条记录
【发布时间】:2018-02-27 17:44:10
【问题描述】:

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

根据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_initialize 等方法在通过nil, {}, false, "" 时仍然返回最后一条记录。

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

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

谢谢!

【问题讨论】:

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


    【解决方案1】:

    这让我相信,如果我将属性传递给 find_by which 为 nil 或什至为空白,则应将其移至 Model.new(nil), 但是,对我来说,它一直返回该模型的最后一条记录。

    不,这是不对的。 find_by() 总是返回第一条记录符合指定条件,在你的情况下没有任何条件,所以返回第一条记录。

    它只返回 nil 如果条件不匹配

    => 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
    

    【讨论】:

    • 我想到的一件事是,它编写了一个自定义方法,它只是 where(foo: nil, bar: nil).find_or_initialize 调用的包装,在将参数传递给 where(foo: nil, bar: nil).find_or_initialize 之前检查参数,该方法可以例如初始化模型Model.new(attr) 并检查它是否有效Model.new(attr).valid?,以避免意外的数据库写入。另请查看Keyword Arguments,它对参数的行为非常严格。
    • 对我来说有点模糊。但是您是否尝试删除 where 闭包并仅使用 Property.find_or_initialize_by(address1: nil, city: nil) { |record| check here if you record persisted }
    • 是关于你的案子github.com/rails/rails/issues/26618 吗?很抱歉,我真的很难在没有代码的情况下诊断问题。我建议你再问一个关于验证问题的问题。
    • 自定义验证怎么样?可能是活动记录挂钩? edgeguides.rubyonrails.org/…可以帮您查看父模型。
    猜你喜欢
    • 1970-01-01
    • 2014-06-17
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 2021-01-31
    • 1970-01-01
    相关资源
    最近更新 更多