Skip to content
Advertisement

Find all records which have a count of an association of zero and none-zero

class Gallery < ApplicationRecord
  has_many :associated_images, as: :imageable
end

class Event < ApplicationRecord
  has_many :associated_images, as: :imageable
end

class Image < ApplicationRecord
  has_many :associated_images
end

class AssociatedImage < ApplicationRecord
  belongs_to :imageable, polymorphic: true
  belongs_to :image
end

I’d like to get all the images which are being used, and a different query to get all the images that are not being used (based on AssociatedImage).

I tried Image.joins(:associated_images).group('images.id').having('count(image_id) > 0') and it returns the correct result. But when I run Image.joins(:associated_images).group('images.id').having('count(image_id) = 0'), it returns an empty #<ActiveRecord::Relation []> and I’m not sure why is that.

My query is based off Find all records which have a count of an association greater than zero‘s discussion

Advertisement

Answer

The reason is that in SQL a count of zero happens when there are no rows. So if there are no rows, even group, there is no result.

What you want is

Image.left_joins(:associated_images).where(associated_images: {id: nil}).group('images.id')

When SQL does a left join, for an image which does not have an associated image, it fills in NULL for all the columns in the associated_images table. So the ones where the associated_images.id is nil, are the ones we want.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement