【问题标题】:Rails 4 find_or_create_by with accepts_nested_attributesRails 4 find_or_create_by 和 accept_nested_attributes_for
【发布时间】:2016-06-21 17:42:02
【问题描述】:

我有以下型号:

class Foo < ActiveRecord::Base
  belongs_to :bar
  accepts_nested_attributes_for :bar
end

class Bar < ActiveRecord::Base
  has_many :foo
end

Bar 包含“对象”,Foo 包含“标签”。

我可以做到以下几点:

f=Foo.create(:label=>"label",:bar_attributes=>{:object=>"mason jar"})

这很好用。

然而,我想要做的是:

f=Foo.find_or_create_by(:label=>"label",:bar_attributes=>{:object=>"mason jar"})

问题是,这会因 SQL 错误而失败

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: bar_attributes.object: SELECT  "foo".* FROM "foo" WHERE "foo"."label" = ? AND "bar_attributes"."object" = 'mason jar' LIMIT 1

我可以理解为什么会发生这种情况,但我希望能够使用该功能。我知道我需要添加代码来为 Bar 执行“find_or_create_by”,但我已经有了这个工作,所以我没有把它放在这里,只是我目前遇到的问题。

那么,有没有办法让 Foo 的“查找”只是忽略 bar_attributes,并且只在必要时使用它(用于创建)?

或者,还有其他方法可以做到这一点吗?

编辑:解释为什么会这样:

我们有两个独立的对象。 Bar 是一个独立的对象。 Foo 是一个包含 Bar 的单独对象类型。

所以,我们可以在 Bar 中有几条记录:

Mason jar
Shovel
Can of corn

我们可以在 Foo 中有其他记录:

label: 123 => Bar: Shovel
label: 456 => Bar: Shovel
label: 123 => Bar: Can of corn

Foo 中的所有 Bar 都是有效的 Bar,但只有 Foo 中带有标签的 Bar 才是 Foo。

所以,基本上,我希望能够运行:

f = Foo.find_or_create_by(:label=>'label',:bar_attributes=>{:object='object'})

如果需要,让它创建 Bar,然后根据需要创建 Foo。

我希望这会有所帮助。

【问题讨论】:

  • 您可以使用 :where 或任何自定义范围链接 find_or_create_by。您是否尝试过在使用 find_or_create_by 之前使用 where 子句?
  • 嗯,一般来说,嵌套属性曾经是一个 gem,后来被合并到 Rails 中,所以任何适用于 ActiveRecord 的东西都不必使用嵌套属性。您是否仅在具有某些属性的 Bar 对象不存在时才尝试创建 Foo 对象?
  • 并非所有代码都在上面。简而言之,我要做的是在 Bar 上运行 find_or_create_by,然后将结果用于 Foo 上的 find_or_create_by。
  • 那么我想你应该先在 Bar 上找到,然后如果需要创建它,最后创建 Foo。这是一种直截了当的方式。为了提出更合适的建议,必须了解您实际在做什么。例如,也许 :reject_if for nested_attributes 可以为您工作。
  • 在原始帖子中添加了更多信息。

标签: ruby-on-rails nested-attributes belongs-to


【解决方案1】:

我猜,你可以这样做:

f = Foo.find_or_create_by(label: 'label', bar: Bar.find_or_create_by(object: 'object'))

相当于

f = Foo.find_or_create_by(label: 'label', bar_id: Bar.find_or_create_by(object: 'object').id)

您可能希望将其设置为两行以检查 Bar 是否已创建(没有验证失败)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    相关资源
    最近更新 更多