我正在尝试实现 Ryan Bates 的可排序表列代码 (Railscast #228),但我希望能够对相关列进行排序。特别是,我有以下模型和关联:
class Project < ActiveRecord::Base
belongs_to :program_manager, :class_name => "User"
class User < ActiveRecord::Base
has_many :program_manager_projects, :class_name => "Project", :foreign_key => "program_manager_id"
项目模型和用户模型之间的关联由“program_manager_id”外键调节,用户使用集合选择下拉菜单在新建/编辑 View 中设置该外键。这是 project.rb 顶部注释的一部分:
# Table name: projects
# program_manager_id :integer
我希望能够按项目经理的姓名(即 project.program_manager.name)对索引 View 中的项目列表进行排序。
理想情况下,我能够以某种方式将 :order 指向这个名称,也许在我的 ProjectsController 的索引方法中使用类似这样的东西:
@projects = Project.find(:all, :order => project.program_manager.name)
但这显然行不通(更不用说 Ryan 的例程通过对要排序的模型中的表名的特定引用来实现这一点。)
我遇到过一些使用 named_scope 的令人生畏的方法,例如:
named_scope :most_active, :select => "questions.*", :joins => "left join comments as comments_for_count on comments_for_count.question.id = questions.id", :group => "questions.id", :order => "count(questions.id) desc"
但鉴于我缺乏 MySQL 专业知识,这对我来说相当难以理解。
任何人都可以帮助我针对我的具体情况概括上面的 named_scope 示例,或者为我指出更直接的策略吗?
非常感谢,
院长
最佳答案
让我们剖析您在上面引用的命名范围。想象一个有很多评论的模型问题。
named_scope :most_active, :select => "questions.*", :joins => "left join comments as comments_for_count on comments_for_count.question.id = questions.id", :group => "questions.id", :order => "count(questions.id) desc"
:most_active
范围的名称。你会这样引用:Question.find(:all).most_active
:select => "questions.*"
默认情况下,scopes 无论如何都会从您的表中选择所有列,因此这将结果限制为仅问题表,而不是评论表。这是可选的。
:joins => "left join comments as comments_for_count on comments_for_count.question.id = questions.id"
这就是说对于每个问题,我还想获得与它们相关的所有评论。评论表有一列“question_id”,我们将使用它来将它们与适当的问题记录相匹配。这个很重要。它允许我们访问不在我们模型中的字段!
:group => "questions.id"
这是 order 子句中的 count() 函数所必需的,它告诉我们我们想要基于问题的评论计数。我们的 order 子句中不需要 count 函数,所以我们也不需要这个 group 语句
:order => "count(questions.id) desc"
按评论数从高到低的顺序返回结果。
因此对于我们的示例,丢弃我们不需要的内容并应用到您的需求中,我们最终得到:
:named_scope :by_program_manager_name, :joins => "left join users on projects.program_manager_id = users.id", :order => "users.name"
这个 named_scope 将被这样调用:
Project.find(:all).by_program_manager_name
注意这基本上等同于:
Project.find(:all, :joins => "left join users on projects.program_manager_id = users.id", :order => "users.name")
但是,正如上面提到的,您应该真正了解底层 SQL。如果没有这种理解,您的能力将受到严重阻碍
关于mysql - 按关联模型中的列对 Rails 数据库表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4663316/