我在不同的地方都读到它在某些情况下会自动推断出来,但是我发现此功能的文档很难遵循。谁能阐明一些原则? 具体来说,Rails何时可以推断,Rails何时不能推断逆?
我想考虑
BundleProduct
和IndividualProduct
都从Product
继承并使用products
表) 某些情况:我正在维护一个具有许多表的相当大的9年历史的Rails应用程序。我想对哪些模型需要添加inverse_of:
有所帮助,而不必更改系统中的每个模型。
答案 0 :(得分:1)
inverse_of
被广泛误解。之所以存在,是因为关联的对象默认情况下不指向相同的内存中对象。
如果您未设置:inverse_of记录,则关联将执行其 最好将自己与正确的逆匹配。自动逆 检测仅对has_many,has_one和belongs_to起作用 协会。
-Rails API docs - ActiveRecord::Associations::ClassMethods
在使用“非标准”命名的情况下,您可能需要提供以下选项:
逆关联的自动猜测使用启发式 基于类的名称,因此它可能不适用于所有人 关联,尤其是具有非标准名称的关联。 -Rails API docs - ActiveRecord::Associations::ClassMethods
例如:
class Pet < ApplicationRecord
belongs_to :owner, class_name: 'User'
end
class User < ApplicationRecord
has_many :pets
end
如果我们调用pet.owner
,即使我们已经加载了该记录,也可能导致数据库命中。
如果我们添加inverse_of
选项:
class Pet < ApplicationRecord
belongs_to :owner, class_name: 'User', inverse_of: :pets
end
class User < ApplicationRecord
has_many :pets, inverse_of: :owner
end
现在,如果我们已经在内存中存储了owner
条记录,那么pet.owner
将指向相同的owner
。
通常,显式设置inverse_of
并没有什么害处,因此可以在不确定的每种情况下进行设置。您还可以通过查看accessing the assocation creates a DB query via the console或在测试套件中使用shoulda-matchers来手动测试是否需要。
答案 1 :(得分:0)
您可以在ActiveRecord::Reflection::AssociationReflection#automatic_inverse_of中查找确切的推断过程。
Rails尝试为has_many
,has_one
和belongs_to
没有through
,foreign_key
选项和范围并且具有标准名称(这是official guide中也有介绍。)