I have a Property
model that has_many :photos
. I want to count the number of properties
that have one or more photo.
How do I do that?
I have tried the simple:
> Property.where('properties.photos.count > ?', 0).count
(3.1ms) SELECT COUNT(*) FROM "properties" WHERE (properties.photos.count > 1)
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "photos"
LINE 1: SELECT COUNT(*) FROM "properties" WHERE (properties.photos....
^
: SELECT COUNT(*) FROM "properties" WHERE (properties.photos.count > 0)
from /ruby-2.3.0@myproject/gems/activerecord-3.2.22.5/lib/active_record/connection_adapters/postgresql_adapter.rb:1163:in `async_exec'
Caused by PG::UndefinedTable: ERROR: missing FROM-clause entry for table "photos"
LINE 1: SELECT COUNT(*) FROM "properties" WHERE (properties.photos....
to:
> Property.joins(:photos).where('photos.count > ?', 0).count
(3.7ms) SELECT COUNT(*) FROM "properties" INNER JOIN "photos" ON "photos"."property_id" = "properties"."id" WHERE (photos.count > 0)
ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: aggregate functions are not allowed in WHERE
LINE 1: ..."photos"."property_id" = "properties"."id" WHERE (photos.cou...
^
: SELECT COUNT(*) FROM "properties" INNER JOIN "photos" ON "photos"."property_id" = "properties"."id" WHERE (photos.count > 0)
from ruby-2.3.0@myproject/gems/activerecord-3.2.22.5/lib/active_record/connection_adapters/postgresql_adapter.rb:1163:in `async_exec'
Caused by PG::GroupingError: ERROR: aggregate functions are not allowed in WHERE
LINE 1: ..."photos"."property_id" = "properties"."id" WHERE (photos.cou...
to the more advanced:
>Property.includes(:photos).group(['property.id', 'photos.id']).order('COUNT(photos.id) DESC').count
(0.6ms) SELECT COUNT(DISTINCT "properties"."id") AS count_id, property.id AS property_id, photos.id AS photos_id FROM "properties" LEFT OUTER JOIN "photos" ON "photos"."property_id" = "properties"."id" GROUP BY property.id, photos.id ORDER BY COUNT(photos.id) DESC
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: missing FROM-clause entry for table "property"
LINE 1: ...CT COUNT(DISTINCT "properties"."id") AS count_id, property.i...
^
: SELECT COUNT(DISTINCT "properties"."id") AS count_id, property.id AS property_id, photos.id AS photos_id FROM "properties" LEFT OUTER JOIN "photos" ON "photos"."property_id" = "properties"."id" GROUP BY property.id, photos.id ORDER BY COUNT(photos.id) DESC
from ruby-2.3.0@myproject/gems/activerecord-3.2.22.5/lib/active_record/connection_adapters/postgresql_adapter.rb:1163:in `async_exec'
Caused by PG::UndefinedTable: ERROR: missing FROM-clause entry for table "property"
LINE 1: ...CT COUNT(DISTINCT "properties"."id") AS count_id, property.i...
and a few other variations, and they all produce similar errors.
What am I doing wrong?
Note: All I want is the count of properties
that have photos.count > 0
. I don't want a hash of all the properties and the count of photos. In other words, if there are 5000 properties in my db, I want to build a scope that returns just the properties that actually have photos.
Since all you want is the Property
s with Photo
s then an INNER JOIN is all you need.
Property.joins(:photos)
That is it. If you want a scope then
class Property < ActiveRecord::Base
scope :with_photos, -> {joins(:photos)}
end
To get the count using rails 3.2
Property.with_photos.count(distinct: true)
You could also use: in rails 3.2
Property.count(joins: :photos, distinct: true)
ActiveRecord::Calculations#count Doc
This will execute
SELECT
COUNT(DISTINCT properties.id)
FROM
properties
INNER JOIN photos ON photos.property_id = properties.id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With