我有三个相关的模型,如以下,每个模型都是上面一个模型的子模型:
class Course < ActiveRecord::Base
has_many :questions
end
class Question < ActiveRecord::Base
belongs_to :course
has_many: :answers
default_scope order: 'questions.created_at DESC'
scope :by_answer_count, -> { #orders Questions based on its answer count
joins(:answers).reorder("count(answers.id) DESC").group(:id)
}
end
class Answer < ActiveRecord::Base
belongs_to :question
end
我很难弄清楚的是:我如何使用Question
模型中的作用域方法by_answer_count
,对我在CoursesController
的index
操作中显示的课程列表进行排序,从最多的答案到最少的答案?有没有一种方法可以利用它,或者我应该在CoursesController
中写一个2层向下的范围方法来让过滤器工作?
谢谢!
您应该能够使用merge来实现这一点。
class Course < ActiveRecord::Base
scope :by_answer_count, joins(:questions).merge(Question.by_answer_count)
end
编辑
合并的工作方式似乎有一个错误。https://github.com/rails/rails/issues/3002
你可以通过添加课程和答案之间的关系来解决这个问题。所以你的课程应该是这样的:
class Course < ActiveRecord::Base
has_many :answers, through: :questions
scope :by_answer_count, joins(:questions).merge(Question.by_answer_count)
end
另一种选择是在Question类中使用手动联接子句。
joins("answers ON answers.question_id = questions.id").reorder(...)
我认为应该在关联上设置一个counter_cache。就像瑞安·贝茨在他的第一部电影中所说的那样:http://railscasts.com/episodes/23-counter-cache-column
我认为以下方法可行:
Course.joins(:questions).order('questions.answer_count DESC')
或范围:
scope :most_answered, joins(:questions).order('questions.answer_count DESC')
它还具有作为单个查询的优点。我没有测试,但应该可以。