繁体   English   中英

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

[英]Sorting a Rails database table by a column in an associated model

我正在尝试实现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。 没有这种理解,你的能力将受到严重阻碍

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM