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

标签 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 => "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/

相关文章:

php - 这些查询可以变成 REPLACE INTO 吗?

r - 有效提取数据框中每列和行的最小值和索引,然后按值排名

python - 如何在 Python 中获得相同的输出示例?

ruby-on-rails - Ruby on Rails : Clear a cached page

javascript - 为什么我的排序不起作用?

mysql - 更改引用表上的主键

mysql - 我的 MySql 查询是否有更短的替代方案?

mysql - 在mysql中创建触发器

javascript - 如何使用 ScriptTags 为 shopify 开发 Rails 应用程序

ruby-on-rails - 将 Postgres 数组列用于 Rails 多对多关系