Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveRecord syntax for finding all items with an average rating of x or greater when using a join

I have two models in my rails application. Items and Reviews. Reviews belong to Item and Items has many Reviews.

The review model looks like this:

create_table "reviews", :force => true do |t|
  t.text     "comment"
  t.integer  "rating"
  t.integer  "reviewable_id"
  t.string   "reviewable_type"
  t.datetime "created_at"
  t.datetime "updated_at"
end

(Reviews are polymorphic so that's why they have a reviewable_id and a reviewable_type)

I'm trying to put together an ActiveRecord query that will allow me to select all Items that have an average rating of of say 80 or more.

I've tried a number of different variations on this which I thought would have worked

Item.joins(:reviews).where("avg(reviews.rating) > 80").group(:id)

however this results in the following error:

Error: Mysql2::Error: Invalid use of group function: SELECT `items`.* FROM `items` INNER JOIN `reviews` ON `reviews`.`reviewable_id` = `items`.`id` AND `reviews`.`reviewable_type` = 'Item' WHERE (avg(reviews.rating) > 80) GROUP BY id

If anyone can help it would be much appreciated.

like image 292
KJF Avatar asked Jan 07 '11 20:01

KJF


People also ask

What is ActiveRecord in Ruby on Rails?

What is ActiveRecord? ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code. When you need to make changes to the database, you'll write Ruby code, and then run "migrations" which makes the actual changes to the database.

What is pluck in Ruby?

ruby rails. Rails has a great, expressive term called pluck that allows you to grab a subset of data from a record. You can use this on ActiveRecord models to return one (or a few) columns. But you can also use the same method on regular old Enumerables to pull out all values that respond to a given key.

What is ActiveRecord relation?

ActiveRecord is an ORM — Object Relational Mapper — written specifically for Ruby connects your application's relational objects to the tables in a relational database. Models are linked together using association types that form relationships between the objects created by your application.


1 Answers

You should put your condition in having instead of where. Meaning:

Item.joins(:reviews).group("reviews.reviewable_id").having("avg(reviews.rating) > ?", 80)
like image 74
krakover Avatar answered Sep 28 '22 00:09

krakover