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版本問題

原來是這樣的:


發表時間

這篇文章是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的一個作用是為了避免二次查詢,提高查詢效率

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容