最近、レール:joins
と:includes
レールの違いについてもっと読んでいました。これが私が理解したことの説明です(例:))
このシナリオを考えてみましょう:
参加:
:joinsは、2つのテーブル間の内部結合を実行します。したがって
Comment.joins(:user)
#=> <ActiveRecord::Relation [#<Comment id: 1, content: "Hi I am Aaditi.This is my first comment!", user_id: 1, created_at: "2014-11-12 18:29:24", updated_at: "2014-11-12 18:29:24">,
#<Comment id: 2, content: "Hi I am Ankita.This is my first comment!", user_id: 2, created_at: "2014-11-12 18:29:29", updated_at: "2014-11-12 18:29:29">,
#<Comment id: 3, content: "Hi I am John.This is my first comment!", user_id: 3, created_at: "2014-11-12 18:30:25", updated_at: "2014-11-12 18:30:25">]>
user_id(コメントテーブルの)がuser.id(usersテーブル)と等しいすべてのレコードをフェッチします。したがって、あなたがするなら
Comment.joins(:user).where("comments.user_id is null")
#=> <ActiveRecord::Relation []>
次のように空の配列を取得します。
さらに、joinは結合されたテーブルをメモリにロードしません。したがって、あなたがするなら
comment_1 = Comment.joins(:user).first
comment_1.user.age
#=>←[1m←[36mUser Load (0.0ms)←[0m ←[1mSELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1←[0m [["id", 1]]
#=> 24
ご覧のとおりcomment_1.user.age
、結果を取得するために、バックグラウンドでデータベースクエリを再度実行します
含まれるもの:
:includesは、2つのテーブル間で左外部結合を実行します。したがって
Comment.includes(:user)
#=><ActiveRecord::Relation [#<Comment id: 1, content: "Hi I am Aaditi.This is my first comment!", user_id: 1, created_at: "2014-11-12 18:29:24", updated_at: "2014-11-12 18:29:24">,
#<Comment id: 2, content: "Hi I am Ankita.This is my first comment!", user_id: 2, created_at: "2014-11-12 18:29:29", updated_at: "2014-11-12 18:29:29">,
#<Comment id: 3, content: "Hi I am John.This is my first comment!", user_id: 3, created_at: "2014-11-12 18:30:25", updated_at: "2014-11-12 18:30:25">,
#<Comment id: 4, content: "Hi This is an anonymous comment!", user_id: nil, created_at: "2014-11-12 18:31:02", updated_at: "2014-11-12 18:31:02">]>
結果として、commentsテーブルのすべてのレコードが結合されたテーブルになります。したがって、あなたがするなら
Comment.includes(:user).where("comment.user_id is null")
#=> #<ActiveRecord::Relation [#<Comment id: 4, content: "Hi This is an anonymous comment!", user_id: nil, created_at: "2014-11-12 18:31:02", updated_at: "2014-11-12 18:31:02">]>
示されているように、comments.user_idがnilであるレコードをフェッチします。
さらに、メモリに両方のテーブルをロードします。したがって、あなたがするなら
comment_1 = Comment.includes(:user).first
comment_1.user.age
#=> 24
ご覧のとおり、comment_1.user.ageは、バックグラウンドでデータベースクエリを実行せずに、メモリから結果をロードするだけです。
includes
(これを読んでいる人にとって)