복붙노트

[RUBY-ON-RAILS] 레일 관련 제로 has_many 기록과 기록을 찾을 [중복]

RUBY-ON-RAILS

레일 관련 제로 has_many 기록과 기록을 찾을 [중복]

이것은 매우 간단 보이지만 나는 구글에 올려 얻을 수 없습니다.

만약 내가 가지고 있다면:

class City < ActiveRecord::Base
  has_many :photos
end

class Photo < ActiveRecord::Base
  belongs_to :city
end

나는 사진이없는 모든 도시를 찾고 싶어요. 내가 좋아하는 뭔가를 호출 할 수 싶네요 ...

City.where( photos.empty? )

...하지만 존재하지 않습니다. 그래서, 당신은 어떻게 이런 종류의 질의를해야합니까?

최신 정보: 이제 원래의 질문에 대한 답을 발견하는 데, 내가 궁금 하군요, 어떻게 역을 구성합니까?

IE : 나는 범위로 다음을 만들려는 경우 :

scope :without_photos, includes(:photos).where( :photos => {:city_id=>nil} )
scope :with_photos, ???

해결법

  1. ==============================

    1.바하마, 여기를 발견 https://stackoverflow.com/a/5570221/417872

    바하마, 여기를 발견 https://stackoverflow.com/a/5570221/417872

    City.includes(:photos).where(photos: { city_id: nil })
    
  2. ==============================

    2.레일 5에서, 사진이없는 모든 도시를 찾기 위해, 당신은 left_outer_joins을 사용할 수 있습니다 :

    레일 5에서, 사진이없는 모든 도시를 찾기 위해, 당신은 left_outer_joins을 사용할 수 있습니다 :

    City.left_outer_joins(:photos).where(photos: {id: nil})
    

    같은 SQL이 발생할 것이다 :

    SELECT cities.*
    FROM cities LEFT OUTER JOIN photos ON photos.city_id = city.id
    WHERE photos.id IS NULL
    

    포함하여 :

    City.includes(:photos).where(photos: {id: nil})
    

    같은 결과를해야하지만 같은 훨씬 더 추악한의 SQL 발생합니다 :

    SELECT cities.id AS t0_r0, cities.attr1 AS t0_r1, cities.attr2 AS t0_r2, cities.created_at AS t0_r3, cities.updated_at AS t0_r4, photos.id AS t1_r0, photos.city_id AS t1_r1, photos.attr1 AS t1_r2, photos.attr2 AS t1_r3, photos.created_at AS t1_r4, photos.updated_at AS t1_r5
    FROM cities LEFT OUTER JOIN photos ON photos.city_id = cities.id
    WHERE photos.id IS NULL
    
  3. ==============================

    3.조인 된 테이블에서 일치하는 레코드 기록을 찾기 위해 노력하는 경우, 당신은 왼쪽 외부 조인을 사용할 필요가

    조인 된 테이블에서 일치하는 레코드 기록을 찾기 위해 노력하는 경우, 당신은 왼쪽 외부 조인을 사용할 필요가

    scope :with_photos, joins('LEFT OUTER JOIN photos ON cities.id = photos.city_id').group('cities.id').having('count(photos.id) > 0')
    scope :without_photos, joins('LEFT OUTER JOIN photos ON cities.id = photos.city_id').group('cities.id').having('count(photos.id) = 0')
    
  4. ==============================

    4.나는이 사진과 함께 모든 사람을 얻기 위해 가입 사용 :

    나는이 사진과 함께 모든 사람을 얻기 위해 가입 사용 :

    범위 : with_photos -> {조인 (: 사진) .distinct}

    쉽게 작성하고 특정 경우에, 이해합니다. 나는 확실히 효율이 일을 무엇인지하지만, 포함하고 대에 가입하고 있지 않다

  5. ==============================

    5.당신은 LEFT OUTER을 가입하고 싶은대로 나는 허용 대답은 당신이 찾고있는 정확하게 당신에게 제공 믿지 않는 그 대답은 당신을 내부 조인 줄 것이다. 레일 5에서 적어도 당신은 사용할 수 있습니다 :

    당신은 LEFT OUTER을 가입하고 싶은대로 나는 허용 대답은 당신이 찾고있는 정확하게 당신에게 제공 믿지 않는 그 대답은 당신을 내부 조인 줄 것이다. 레일 5에서 적어도 당신은 사용할 수 있습니다 :

    scope :without_photos, left_joins(:photos).where( photos: {id: nil} )
    

    네임 스페이스 지정이 곳 절 복잡 할 곳 또는 당신이 경우에 병합을 사용할 수 있습니다 :

    scope :without_photos, left_joins(:photos).merge( Photos.where(id: nil) )
    
  6. ==============================

    6.당신이 레일을 5+ 실행되지 않고 성능이 경우 단지 당신이 필요, 반드시이 쓸모없는 액티브 생성을 방지하고 얻을 :

    당신이 레일을 5+ 실행되지 않고 성능이 경우 단지 당신이 필요, 반드시이 쓸모없는 액티브 생성을 방지하고 얻을 :

    City.where("NOT EXISTS(SELECT 1 FROM photos WHERE photos.city_id = cities.id LIMIT 1)")
    
  7. from https://stackoverflow.com/questions/9613717/rails-find-record-with-zero-has-many-records-associated by cc-by-sa and MIT license