mysql – 按关联模型中的列对Rails数据库表进行排序

我正在尝试实现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"

Project模型和User模型之间的关联由’program_manager_id’外键调解,用户使用collection-select下拉列表在new / edit视图中设置该外键.这是project.rb顶部注释的一部分:

# Table name: projects
# program_manager_id :integer

我希望能够通过程序管理器的名称(即project.program_manager.name)在索引视图中对项目列表进行排序.

理想情况下,我能够指出:以某种方式命令这个名字,也许在我的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.*"

默认情况下,作用域会选择表中的所有列,因此这会将结果限制为仅限问题表,而不是注释表.这是可选的.

: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")

但是,正如上面提到的cam,您应该真正了解底层SQL.没有这种理解,你的能力将受到严重阻碍

上一篇:Python的平凡之路(7)


下一篇:Java NIO.2 使用Files类遍历文件夹