1

Im having trouble figuring out how to write a multi-layer sort using a scope method in my model, which can sort through the model's attributes, as well as its related child models' attributes?

To put more concretely, I have the following models, each a related child of the previous one (I excluded other model methods and declarations for brevity):

class Course < ActiveRecord::Base 
  has_many :questions
  # would like to write multi-layer sort here 
end 

class Question < ActiveRecord::Base 
  belongs_to :course, :counter_cache => true
  has_many: :answers

end 

class Answer < ActiveRecord::Base 
  belongs_to :question, :counter_cache => true
end

I would like to sort courses first by questions_count (through my counter_cache), then by answer_count, and lastly by created_at, and was wondering how I could string everything together into a single scope method to put in my Course model.

Thanks.

1 Answer 1

4

As seen here (creating a scope with a joined model) : problem: activerecord (rails3), chaining scopes with includes

And here (sorting with multiple columns) : Ruby on Rails: how do I sort with two columns using ActiveRecord?

And finally here (sorting by associated model) : Rails 3. sort by associated model

You may achieve this like so :

scope :complex_sorting, lambda {
    joins(:questions)
    .order('questions_count DESC, question.answers_count DESC, created_at DESC')
}
Sign up to request clarification or add additional context in comments.

10 Comments

Typing in the code as seen above resulted in a "tried to create Proc object without a block" error. After seeing a similar issue raised, I reformatted the code as scope :by_most_popular, lambda { |course| joins(:question).order('questions_count DESC, question.answers_count DESC, created_at DESC') }. However, now Ruby is complaining that "wrong number of arguments (0 for 1)"
Updated my answer to replace "do...end" with curly brackets. Do you have more precisions regarding the "wrong number of arguments error (0 for 1)" ?
I did a bit more digging around to find out whats behind the "wrong arguments" error. I rewrote a simpler scope method to test if the joins is working (scope :by_answer_count, -> { joins(:question).order('question.answers_count DESC') }) and I got the error "Association named 'question' was not found; perhaps you misspelled it?". Given the way the models are related, i don't see why its can't find the question model. I think its likely this was throwing the more complex sorting method off.
Maybe it's :questions and not :question given the has_many relation ?
My mistake, I think you don't need to pass the argument (as your first error said) juste remove the |course|. It is used in case you pass an argument to your scope... sorry about that
|

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.