Verse _ of 做什么? 它生成什么 SQL?

我试图让我的头围绕 inverse_of和我不明白它。

如果有的话,生成的 sql 是什么样子的?

如果与 :has_many:belongs_to:has_many_and_belongs_to一起使用,inverse_of选项是否表现出相同的行为?

如果这是一个基本的问题,我很抱歉。

我看到了这个例子:

class Player < ActiveRecord::Base
has_many :cards, :inverse_of => :player
end


class Card < ActiveRecord::Base
belongs_to :player, :inverse_of => :cards
end
63341 次浏览

文件来看,似乎 :inverse_of选项是一种避免 SQL 查询而不是生成它们的方法。它提示 ActiveRecord 使用已加载的数据,而不是通过关系再次获取数据。

他们的例子是:

class Dungeon < ActiveRecord::Base
has_many :traps, :inverse_of => :dungeon
has_one :evil_wizard, :inverse_of => :dungeon
end


class Trap < ActiveRecord::Base
belongs_to :dungeon, :inverse_of => :traps
end


class EvilWizard < ActiveRecord::Base
belongs_to :dungeon, :inverse_of => :evil_wizard
end

在这种情况下,调用 dungeon.traps.first.dungeon应该返回原来的 dungeon对象,而不是像默认情况那样加载一个新对象。

如果您有一个 has_many_through之间的关系,两个模型,用户和角色,并希望验证连接模型分配对不存在或无效的条目与 validates_presence of :user_id, :role_id,它是有用的。您仍然可以使用 User@User 及其关联 @user.role(params[:role_id])生成 User@User,以便保存该用户不会导致对分配模型的验证失败。

只是一个更新给大家-我们刚刚使用 inverse_of与我们的一个应用程序与 has_many :through协会


它基本上使“原点”对象对“子对象”可用

因此,如果你使用 Rails 的例子:

class Dungeon < ActiveRecord::Base
has_many :traps, :inverse_of => :dungeon
has_one :evil_wizard, :inverse_of => :dungeon
end


class Trap < ActiveRecord::Base
belongs_to :dungeon, :inverse_of => :traps
validates :id,
:presence => { :message => "Dungeon ID Required", :unless => :draft? }


private
def draft?
self.dungeon.draft
end
end


class EvilWizard < ActiveRecord::Base
belongs_to :dungeon, :inverse_of => :evil_wizard
end

使用 :inverse_of将允许您访问与之相反的数据对象,而无需执行任何进一步的 SQL 查询

我认为 :inverse_of对于处理那些还没有被坚持下来的关联是最有用的。例如:

class Project < ActiveRecord::Base
has_many :tasks, :inverse_of=>:project
end


class Task < ActiveRecord::Base
belongs_to :project, :inverse_of=>:tasks
end

现在,在控制台里:

irb> p = Project.new
=> #<Project id: nil, name: nil, ...>
irb> t = p.tasks.build
=> #<Task id: nil, project_id: nil, ...>
irb> t.project
=> #<Project id: nil, name: nil, ...>

如果没有 :inverse_of参数,t.project将返回 nil,因为它触发一个 sql 查询,而数据尚未存储。使用 :inverse_of参数,可以从内存中检索数据。

当我们有两个模型具有 has _ many 并且属于 _ to 关系时,最好使用反向函数,通知 ActiveRecod 它们属于关联的同一方。因此,如果来自一端的查询被触发,那么如果来自相反方向的查询被触发,那么它将从缓存中缓存并提供服务。提高了性能。在 Rails 4.1中,如果我们使用 foreign _ key 或者改变类名称,我们需要显式地设置参数,则自动设置 verse _ of。

最佳细节和示例文章。

Http://viget.com/extend/exploring-the-inverse-of-option-on-rails-model-associations

在此之后,在大多数情况下不需要 相反的,相反的

ActiveRecord 支持大多数与标准名称的关联的自动识别。但是,ActiveRecord 不会自动识别包含范围或下列任何选项的双向关联:

  • 校对: through
  • 翻译: foreign _ key
class Author < ApplicationRecord
has_many :books, inverse_of: 'writer'
end


class Book < ApplicationRecord
belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
end


a = Author.first
b = a.books.first
a.first_name == b.writer.first_name # => true
a.first_name = 'David'
a.first_name == b.writer.first_name # => true

在上面的示例中,对同一对象的引用存储在变量 a和属性 writer中。