Mysql 按关联模型中的列对Rails数据库表进行排序
我试图实现Ryan Bates的可排序表列代码(Railscast#228),但我希望能够对相关列进行排序。特别是,我有以下模型和关联:Mysql 按关联模型中的列对Rails数据库表进行排序,mysql,ruby-on-rails,sorting,associations,named-scope,Mysql,Ruby On Rails,Sorting,Associations,Named Scope,我试图实现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 =
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"
我希望能够按照项目经理的姓名,即project.program_manager.name,对索引视图中的项目列表进行排序
理想情况下,我能够以某种方式指向:order这个名称,也许在我的ProjectsController的index方法中有类似的东西:
@projects = Project.find(:all, :order => project.program_manager.name)
但这显然行不通(更不用说Ryan的例程通过对要排序的模型中的表名的特定引用来实现这一点)
我遇到了一些使用命名范围的可怕方法,例如:
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专业知识,这对我来说是相当难以理解的
有谁能帮我概括一下上面的命名范围示例以适合我的具体情况,或者给我一个更简单的策略
非常感谢
Dean让我们剖析一下您上面提到的命名范围。想象一个有许多注释的模型问题
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)。最活跃
:select => "questions.*"
默认情况下,作用域会选择表中的所有列,因此这会将结果限制为仅显示问题表,而不显示注释表。这是可选的
:joins => "left join comments as comments_for_count on comments_for_count.question.id = questions.id"
这意味着对于每一个问题,我也希望得到与之相关的所有评论。comments表有一列'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"
此命名的_范围将被称为:
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。如果没有这种理解,您的能力将受到严重影响使用ORM作为不学习SQL的借口是个坏主意。仔细阅读连接。这似乎是一个很好的高层次概述:重点是。。。谢谢你的有用的文章链接!我会接受你的建议,不再拖延研究SQL。这正是我想要的答案。谢谢你花时间把事情说得这么清楚。按照你的建议,我可以修改RailsaST代码,以完成我想要的。正如我在给Cam的消息中所指出的,您强烈地激励我坐下来研究ActiveRecord“魔力”背后的SQL。
Project.find(:all, :joins => "left join users on projects.program_manager_id = users.id", :order => "users.name")