Reputation: 367
I have a ActiveRecord query I’ve been working with (history here) that works great in MySQL, but now I need to convert my database to PostgreSQL and I'm getting an error. Here is the query:
class Shoe < ActiveRecord::Base
has_many :purchases
def self.available_shoes
#show all shoes that have been purchased less than num_in_stock
num_in_stock = 3
Shoe.includes(:purchases)
.group("purchases.shoe_id")
.having("COUNT(purchases.shoe_id) < ?", num_in_stock)
end
end
Simply switching the gems and adapters to postgres is not enough: I now get the following error:
ActionView::Template::Error (PG::Error: ERROR: column "shoes.id" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: SELECT "shoes"."id" AS t0_r0, "shoes"."created_at" AS ...
I tried changing
.group("purchases.shoe_id")
to
.group("purchases.shoe_id, shoes.id, purchases.id")
and while this got rid of the error, it also changed the sql and broke some of my tests.
I have read many stackoverflow questions regarding this error but I was unable to find a solution. What do I need to change in my ActiveRecord query to make this work in postgres?
Thanks in advance!
Upvotes: 1
Views: 595
Reputation: 2973
Did you found solution? If not try:
Shoe.where("not exists ( select 1 from purchases where shoe_id = shoes.id offset ? limit 1)", num_in_stock - 1)
It will be slow for big num_in_stock and you should have index on purchases.shoe_id column.
I think that there is no fast solution on large tables unless you have already counted purchases.
EDIT
Consider using counter_cache or counter_culture gem
Upvotes: 1