找到没有has_many的记录:通过关联

时间:2016-02-01 14:20:06

标签: ruby-on-rails activerecord

我有3张桌子:
advert.rb

class Advert < ActiveRecord::Base
  has_many :postings, dependent: :destroy
  has_many :sites, through: :postings
end

posting.rb

class Posting < ActiveRecord::Base
  belongs_to :advert
  belongs_to :site
end

site.rb

class Site < ActiveRecord::Base
end

我需要找到没有帖子的广告将这些广告链接到所有网站(至少有一个网站没有链接到的广告)。我应该写什么查询? 我试过了

Advert.joins(
  "LEFT JOIN postings ON postings.advert_id = adverts.id " +
  "JOIN sites ON sites.id = postings.site_id").
  group('adverts.id').having('COUNT(sites.id) = 0')

但它似乎无法发挥作用。

我的规格:

site1 = create :site
site2 = create :site
advert1 = create :advert
advert2 = create :advert
create(:posting, advert: advert1, site: site1)
create(:posting, advert: advert1, site: site2)
create(:posting, advert: advert2, site: site1)
expect(Advert.not_posted).to match_array([advert2])

3 个答案:

答案 0 :(得分:2)

以下是您的查询:

Advert.includes(postings: :sites).where(sites: { id: nil })

您可能希望通读ActiveRecord querying guide

答案 1 :(得分:1)

  

至少有一个与之无关的网站的广告

所以相同的逻辑是:

  • A =查找属于所有postings
  • sites
  • 最终结果=与{strong> A 无关的adverts

我的查询是这样的:

a_query = %Q{
  SELECT advert_id
  FROM postings
  GROUP BY advert_id
  HAVING COUNT(DISTINCT site_id) = #{Site.count}
}

result = Advert.where("id NOT IN (#{a_query})")

答案 2 :(得分:0)

您想让所有广告都没有任何网站吗?像这样轻松

Advert.where.not(id: Posting.select(:advert_id))