ActiveRecord에서 merge에서 joins를 실행하면 거동이 바뀝니다.
4148 단어 RailsActiveRecord
상황
(Rails 5.0.0에서 확인)
class A
belongs_to :B
end
class B
has_one :A
has_one :C
scope :with_c, -> { joins(:c) }
scope :without_c, -> { left_outer_joins(:c).merge(C.where(id: nil)) }
end
class C
belong_to :B
end
> B.with_c.to_sql
SELECT "bs".* FROM "bs" INNER JOIN "cs" ON "cs"."b_id" = "bs"."id"
> A.joins(:b).merge(B.with_c).to_sql
SELECT "as".* FROM "as" INNER JOIN "bs" ON "bs"."id" = "as"."b_id" LEFT OUTER JOIN "cs" ON "cs"."b_id" = "bs"."id"
> B.without_c.to_sql
SELECT "bs".* FROM "bs" INNER JOIN "cs" ON "cs"."b_id" = "bs"."id" WHERE "cs"."id" IS NULL
> A.joins(:b).merge(B.without_c).to_sql
ActiveRecord::ConfigurationError: Can't join 'A' to association named 'c'; perhaps you misspelled it?
from /path/to/activerecord-5.0.0/lib/active_record/associations/join_dependency.rb:231:in `find_reflection'
질문
INNER JOIN인가 OUTER JOIN인가로 치명적으로 거동이 바뀌어 버리는 로직을 쓰려고 합니다만, 그러한 쿼리 내용을 안정시키고 싶은 경우 여러분 어떻게 하고 있을까요?
지금 생각하고 있는 해결안
class A
belongs_to :B
end
class B
has_one :A
has_one :C
scope :with_c, -> { joins(:c) }
scope :without_c, -> { left_outer_joins(:c).merge(C.where(id: nil)) }
end
class C
belong_to :B
end
> B.with_c.to_sql
SELECT "bs".* FROM "bs" INNER JOIN "cs" ON "cs"."b_id" = "bs"."id"
> A.joins(:b).merge(B.with_c).to_sql
SELECT "as".* FROM "as" INNER JOIN "bs" ON "bs"."id" = "as"."b_id" LEFT OUTER JOIN "cs" ON "cs"."b_id" = "bs"."id"
> B.without_c.to_sql
SELECT "bs".* FROM "bs" INNER JOIN "cs" ON "cs"."b_id" = "bs"."id" WHERE "cs"."id" IS NULL
> A.joins(:b).merge(B.without_c).to_sql
ActiveRecord::ConfigurationError: Can't join 'A' to association named 'c'; perhaps you misspelled it?
from /path/to/activerecord-5.0.0/lib/active_record/associations/join_dependency.rb:231:in `find_reflection'
INNER JOIN인가 OUTER JOIN인가로 치명적으로 거동이 바뀌어 버리는 로직을 쓰려고 합니다만, 그러한 쿼리 내용을 안정시키고 싶은 경우 여러분 어떻게 하고 있을까요?
지금 생각하고 있는 해결안
scope :without_c, -> { joins("LEFT OUTER JOIN cs ON cs.b_id = bs.id").merge(C.where(id: nil)) }
정답?
h tps : // 게임 m 없음 m. 코 m / 게 ms / 아 c 치오 레코 rd / ぇ r 시온 s / 4.0.0에서
The solution is to build JoinAssociation when two relations with join information are being merged. And later while building the Arel use the previously built JoinAssociation record in JoinDependency#graft to build the right from clause. Fixes #3002.
라고 쓰여져 있습니다만, how to build JoinAssociation 를 몰랐다
Reference
이 문제에 관하여(ActiveRecord에서 merge에서 joins를 실행하면 거동이 바뀝니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/urakawa/items/5cdfb660dbebe9c4bab4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)