【问题标题】:Rails foo= vs foo_id=Rails foo= vs foo_id=
【发布时间】:2015-08-18 13:30:01
【问题描述】:

如果barbelongs_to foo和foo has_many bar,效果有区别吗

my_bar.foo = my_foo

my_bar.foo_id = my_foo.id

或者两者都在 my_foo 和 my_bar 之间建立关联?

我之所以问,是因为当我覆盖 Bar#foo_id=(input) 的设置器时,我正试图决定是否手动添加关联。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    您的问题有一点不准确,因为这些都没有创建关联:他们设置了关联(如果您愿意,可以“构建”它),但是它不会被创建,即保存到数据库中,直到my_bar保存

    这两者应该互相设置代理:如果你说my_bar.foo_id = 4,那么my_bar.foo应该返回id为4的foo,甚至它被保存之前,反之亦然。

    如果您要覆盖 Bar#foo_id 的 setter(按照惯例,在描述方法时,哈希表示实例方法而不是类方法),如果您不复制自然的方法,您可能会遇到麻烦Rails 的行为。小心行事。

    【讨论】:

    • 我使用“create”太松散了,不是正式意义上的。我会更新我的问题。感谢您的答复。这正是我需要知道的。
    【解决方案2】:

    主要区别是bar_id要等到Bar记录被保存后才能填写(分配id属性时)。在保存任一记录之前,您可以在内存中构建一个 Bar 对象并将其与一个 bar(foo = 部分)相关联。通常,当您保存 Bar 时,foo 也会被验证并保存。

    • foo_id 是要保存到数据库的属性,它将引用 FOOS 表中的一条记录。
    • foo 是一个实例化的 ActiveRecord 对象,它作为 bar 对象的属性存储。

    通常,如果您将新 Bar 与现有 foo 关联,我会设置 foo_id。如果你同时创建它们,我会设置 foo。

    编辑:看到你问题的最后一部分。如果您覆盖 setter 以添加功能,我将首先调用 super(value) 从 ActiveRecord 获取所有现有功能。例如

    def foo_id=(value)
      super(value)
      @foo_id = value
      do_other_thing
    end
    

    我建议以删除此功能的方式覆盖此方法。

    【讨论】:

      猜你喜欢
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 2014-03-20
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 2011-01-11
      • 2018-11-14
      相关资源
      最近更新 更多