我最近在阅读有关Rails :joins
和:includes
Rails 之间差异的更多信息。这是我所理解的解释(带有示例:))
考虑这种情况:
加入:
:joins 在两个表之间执行内部联接。从而
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(用户表)的所有记录。因此,如果你这样做
Comment.joins(:user).where("comments.user_id is null")
#=> <ActiveRecord::Relation []>
您将得到一个空数组,如图所示。
此外,联接不会将联接的表加载到内存中。因此,如果你这样做
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 在两个表之间执行左外部联接。从而
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">]>
将导致一个合并表和注释表中的所有记录。因此,如果你这样做
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">]>
如图所示,它将获取注释.user_id为零的记录。
而且包括将两个表都加载到内存中。因此,如果你这样做
comment_1 = Comment.includes(:user).first
comment_1.user.age
#=> 24
如您所见,comment_1.user.age只是从内存中加载结果,而无需在后台触发数据库查询。
includes
(对于阅读此文件的任何人)