1

I have a custom model called product, and it has many reviews.

i have a method that calculates the review

def rating
    total = 0
    reviews_count = reviews.count

    return 0 if reviews_count == 0

    reviews.each do |review|
        total += review.grade
    end

    total.to_f/reviews_count
end

i would like to know how could i use this method to Order my products.

At products_controller.rb, if i use:

@products = Product.all.order("price")

its easy, it gives me the products list ordered by price. But, if i use, for example:

@products = Product.all.sort_by{|p| p.rating}

it gives me an array and not a "ActiveRecord::Relation"

I would like to know how could i order my product using a custom method that returns a value.

2 Answers 2

1

In general, you can't. Ordering happens in your database, which has no knowledge about any method you typed in your application. What you need is a way of translating your method into a valid sql. In your case, you can do:

Product.joins(:reviews).group('products.id').order('AVG(reviews.grade)')

That will give you sorted results and the relation object. However, relations with join are not that nice to work with, especially if you try to add another join. Also this might get quite slow when your database grows.

Sign up to request clarification or add additional context in comments.

Comments

0

What you're doing in your example is running the query then using sort_by to sort the result set.

If you want to get back an activerecord collection instead of an array, and potentially chain this with other scopes, you should move the logic from your method into SQL, and put it in a scope.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.