inverse_of到底在rails中有啥用?

玩inverse_of的时候,会疑惑这家伙到底有什么用?

就查到https://www.viget.com/articles/exploring-the-inverse-of-option-on-rails-model-associations这篇文章,这里面讲:
如果建立prison和criminal这样一对多关系的两个model:

class Criminal < ActiveRecord::Base
 belongs_to :prison, inverse_of: :criminals
end

class Prison < ActiveRecord::Base
 has_many :criminals, inverse_of: :prison
end

然后:

prison = Prison.create(name: 'Bad House')
criminal = prison.criminals.create(name: 'Krazy 8')

当去掉inverse_of的时候,会再次查询数据库

# Without :inverse_of
criminal.prison == prison
# Prison Load (0.1ms) SELECT "prisons".* FROM "prisons" WHERE "prisons"."id" = 2 LIMIT 1
# => true

加上inverse_of时,就直接从内存中找

# With :inverse_of
criminal.prison == prison
# => true

但是,当我去掉inverse_of时,并没有出现:

# Prison Load (0.1ms) SELECT "prisons".* FROM "prisons" WHERE "prisons"."id" = 2 LIMIT 1

当时就想可能是rails console不显示这样的查询过程吧(原谅我的无知),后来就用pry看rails server的过程,也没出现。当时也想过可能是rails版本的问题,rails -v看下,但是没有继续深究下去,如果当时朝着这方向就好了。

继续google,发现这篇文章https://ruby-china.org/topics/24998才明白,原来真的是rails版本问题

原来是这样的:


inverse_of到底在rails中有啥用?_第1张图片
发表时间

这篇文章是2014年发表的,可能当时作者的环境还是rails 4.1以前的,rails4.1以后的版本是默认带有inverse_of的,github上是这样说的:

rails4.1 automatic inverse_of breaks existing relation on polymorphic association #15337

链接:https://github.com/rails/rails/issues/15337

也就是说,rails4.1版本会

所以,作者直接去掉inverse_of,prison.criminals时是会再次查询数据库的,也就是会显示下面这样:

# Prison Load (0.1ms) SELECT "prisons".* FROM "prisons" WHERE "prisons"."id" = 2 LIMIT 1

最后总结:inverse_of的一个作用是为了避免二次查询,提高查询效率

你可能感兴趣的:(inverse_of到底在rails中有啥用?)