带有 ActiveRecord 的 rails 3 中的 inverse_of 有啥限制

Posted

技术标签:

【中文标题】带有 ActiveRecord 的 rails 3 中的 inverse_of 有啥限制【英文标题】:what are the limitations of inverse_of in rails 3 with ActiveRecord带有 ActiveRecord 的 rails 3 中的 inverse_of 有什么限制 【发布时间】:2013-04-18 07:21:15 【问题描述】:

我一直在阅读有关 inverse_of 的内容,而我在网上看到的所有内容似乎都不一致并且让我感到困惑。如果你看here,你可以看到

inverse_of 支持有一些限制:

它们不适用于 :through 关联。 它们不适用于 :polymorphic 关联。 它们不适用于 :as 关联。 对于belongs_to 关联,has_many 反向关联被忽略。

在此之上,他们给出了这个例子

class Customer < ActiveRecord::Base
   has_many :orders, :inverse_of => :customer
end

class Order < ActiveRecord::Base
   belongs_to :customer, :inverse_of => :orders
end

我认为他们是在说第一个 inverse_of 什么都不做,但如果是这样,他们为什么要这样做?

此外,即使上面说 inverse_of 不能通过关联工作,this page 说

如果您在连接模型上使用belongs_to,最好在belongs_to 上设置:inverse_of > 选项,这意味着以下示例在>tags 是has_many :through 关联的情况下可以正常工作):

并给出这个例子

@post = Post.first
@tag = @post.tags.build :name => "ruby"
@tag.save

最后一行应该保存直通记录(Taggable)。这仅在设置 >:inverse_of 时才有效:

class Taggable < ActiveRecord::Base
  belongs_to :post
belongs_to :tag, :inverse_of => :taggings
end

对我来说,所有这些似乎都不一致且非常混乱。但总的来说,我认为对每个关系都说 inverse_of 并没有什么坏处。那是问题吗?我看到很多人在 SO 上问这个问题,但没有看到任何人给出明确的“是”或“否”。

【问题讨论】:

【参考方案1】:

始终指定它并没有什么害处,它允许rails优化对象的加载,因此您可以在两个方向上上下活动记录模型关系链,而不会出现奇怪的错误,即更改一个对象的值不会更改它的参考。

将它设置在不起作用的地方的唯一问题是您之前所说的某些类型,如果它们静默失败,如果您在更改某些内容后在方法链中走错路,您将得到前面提到的错误

这是来自 rails API

d = Dungeon.first
t = d.traps.first
d.level == t.dungeon.level # => true
d.level = 10
d.level == t.dungeon.level # => false

上述示例中的 Dungeon 实例 d 和 t.dungeon 引用数据库中的相同对象数据,但实际上是该数据的不同内存副本。在关联上指定 :inverse_of 选项可以告诉 Active Record 反向关系,它会优化对象加载。

【讨论】:

以上是关于带有 ActiveRecord 的 rails 3 中的 inverse_of 有啥限制的主要内容,如果未能解决你的问题,请参考以下文章

带有 has_many belongs_to 关联的 Rails activerecord 查询

使用 Rails 6 ActiveRecord 进行完全外连接

如何在带有 squeel 的 Rails 中使用连接

Rails 3 包括翻译 globalize3 activerecord

Rails - 使用ActiveRecord :: Enum时的ArgumentError

ActiveRecord / Rails 3 中的日期格式