我最近阅读了更多关于rails之间:joins
和之间的区别。:includes
这是对我理解的解释(带有示例:))
考虑这种情况:
加入:
: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">]>
它将获取 comments.user_id 为 nil 的记录,如图所示。
此外,还包括将两个表都加载到内存中。因此,如果你这样做
comment_1 = Comment.includes(:user).first
comment_1.user.age
#=> 24
如您所见,comment_1.user.age 只是从内存中加载结果,而无需在后台触发数据库查询。