나는 최근의 차이에 더 읽고 있었다 :joins
및 :includes
레일한다. 여기에 내가 이해 한 것에 대한 설명이 있습니다 (예 :))
이 시나리오를 고려하십시오.
사용자는 사용자에게 많은 댓글과 댓글이 있습니다.
사용자 모델에는 Name (string), Age (integer) 속성이 있습니다. 주석 모델에는 Content, user_id 속성이 있습니다. 주석의 경우 user_id는 null 일 수 있습니다.
조인 :
: 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 (users 테이블)와 같은 모든 레코드 를 가져옵니다 . 따라서 당신이 할 경우
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">]>
comment.user_id가 nil 인 레코드를 표시된대로 가져옵니다.
또한 메모리에 두 테이블을 모두로드합니다. 따라서 당신이 할 경우
comment_1 = Comment.includes(:user).first
comment_1.user.age
#=> 24
알 수 있듯이 comment_1.user.age는 백그라운드에서 데이터베이스 쿼리를 실행하지 않고 단순히 메모리에서 결과를로드합니다.
includes
(이 글을 읽는 사람에게는)