如何通过 Ruby on Rails 中的关联订购 has_many?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2205618/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:15:08  来源:igfitidea点击:

How do I order a has_many through association in Ruby on Rails?

ruby-on-railshas-many-through

提问by rswolff

Given the following AR models, I would like to sort users alphabetically by last name when given a handle to a task:

鉴于以下 AR 模型,我想在获得任务句柄时按姓氏的字母顺序对用户进行排序:

#user
has_many :assignments
has_many :tasks, :through => :assignments    

#assignment
belongs_to :task
belongs_to :user

#task
has_many :assignments
has_many :users, :through => :assignments

I would like to get a task then navigation to its assigned users, and sort the user list alphabetically.

我想获得一个任务,然后导航到其分配的用户,并按字母顺序对用户列表进行排序

I keep thinking that I should be able to add the :orderclause to has_many :users, :through => :assignmentslike this:

我一直认为我应该能够像这样添加:order子句has_many :users, :through => :assignments

#task.rb
has_many :assignments
has_many :users, :through => :assignments, :order => 'last_name, first_name'

however this does not work.

但是这不起作用。

How can I sort users by last_namewhen given a task?

如何根据last_name给定任务对用户进行排序?

回答by Daniel

Since condition arguments are deprecated in Rails 4, one should use scope blocks:

由于 Rails 4 中不推荐使用条件参数,因此应该使用作用域块:

has_many :users, -> { order 'users.last_name, users.first_name' }, :through => :assignments

回答by Martin T.

Rails 3.x version:

Rails 3.x 版本:

has_many :users, :through => :assignments, :order => 'users.last_name, users.first_name'

UPDATE: This only works in Rails 3.x (maybe before that too). For 4+, see other answers.

更新:这只适用于 Rails 3.x(也许在那之前)。对于 4+,请参阅其他答案。

回答by denis.peplin

The M.G.Palmer'sapproach works well, however table name is involved. There is a better way to do it:

M.G.Palmer's方法运行良好,但涉及表名。有一个更好的方法来做到这一点:

has_many :users, :through => :assignments, :order => [ :last_name, :first_name ]

回答by Antony Sastre

Would this work for you?

这对你有用吗?

# User.rb

class User < ActiveRecord::Base
 default_scope :order => 'last_name ASC'
 ...
end

You can define other named scopes for when sorting needs to be different.

当排序需要不同时,您可以定义其他命名范围。

http://ryandaigle.com/articles/2008/11/18/what-s-new-in-edge-rails-default-scoping

http://ryandaigle.com/articles/2008/11/18/what-s-new-in-edge-rails-default-scoping

回答by edx

This works for me (Rails 4.2)

这对我有用(Rails 4.2)

Applying an ordering on the through map is not preserved, aka this is not enough to have the genres ordered:

不会保留在直通地图上应用排序,也就是这不足以对流派进行排序:

has_many    :disk_genre_maps,
            -> {order('disk_genre_map.sort_order')},
            :inverse_of => :disk,
            :dependent  => :destroy,
            :autosave   => true


has_many    :genres,    # not sorted like disk_genre_maps
            :through    => :disk_genre_maps,
            :source     => :genre,
            :autosave   => true

So I overwrite this per instance:

所以我每个实例都覆盖这个:

def genres  # redefine genres per instance so that the ordering is preserved
    self.disk_genre_maps.map{|dgm|dgm.genre}
end

To make that work for assignments, this should be something like this (untested)

为了使这项工作适用于作业,这应该是这样的(未经测试)

def genres= some_genres
    self.disk_genre_maps = some_genres.map.with_index do |genre, index|
        DiskGenreMap.new(disk:self, genre:genre, sort_order:index)
    end
end

回答by Ricardo Emerson

I am using Rails (5.0.0.1) and could make the sort with this syntax in my model Group that has many users through group_users:

我正在使用 Rails (5.0.0.1),并且可以在我的模型组中使用此语法进行排序,该组通过 group_users 拥有许多用户:

# Associations.
has_many :group_users
has_many :users, -> { order(:name) }, through: :group_users

Adjust the code to your need that will work.

根据您的需要调整代码,使其有效。

回答by Yogzzz

You could also create a new 'sort_order' column on the assignment table, and add a default scope like

您还可以在分配表上创建一个新的“sort_order”列,并添加一个默认范围,如

default_scope { order('sort_order desc')}

to your assignments model.

到你的任务模型。

回答by user223697

has_many :users, -> { order(:last_name, :first_name) }, :through => :assignments, source: 'user'

has_many :users, -> { order(:last_name, :first_name) }, :through => :assignments, source: 'user'