Как мне заказать has_many через ассоциацию в Ruby on Rails? - PullRequest
57 голосов
/ 05 февраля 2010

Учитывая следующие модели 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

Я хотел бы получить задачу, затем перейти к назначенным пользователям, и отсортировать список пользователей по алфавиту .

Я продолжаю думать, что смогу добавить предложение :order к has_many :users, :through => :assignments следующим образом:

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

однако это не работает.

Как я могу отсортировать пользователей по last_name при выполнении задания?

Ответы [ 8 ]

68 голосов
/ 02 октября 2013

Поскольку аргументы условия устарели в Rails 4, следует использовать блоки области действия:

has_many :users, -> { order 'users.last_name, users.first_name' }, :through => :assignments
37 голосов
/ 18 октября 2011

Rails 3.x версия:

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

ОБНОВЛЕНИЕ: Это работает только в Rails 3.x (возможно, до этого тоже). Для 4+ см. Другие ответы.

12 голосов
/ 24 сентября 2012

Подход M.G.Palmer's работает хорошо, однако используется имя таблицы. Есть лучший способ сделать это:

has_many :users, :through => :assignments, :order => [ :last_name, :first_name ]
7 голосов
/ 05 февраля 2010

Будет ли это работать для вас?

# User.rb

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

Вы можете определить другие именованные области, когда сортировка должна быть другой.

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

6 голосов
/ 31 июля 2015

Это работает для меня (Rails 4.2)

Применение порядка на сквозной карте не сохраняется, иначе этого недостаточно для упорядочения жанров:

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

Поэтому я перезаписываю это для каждого экземпляра:

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

Чтобы это работало для заданий, это должно быть примерно так (не проверено)

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
4 голосов
/ 27 декабря 2016

Я использую Rails (5.0.0.1) и могу выполнить сортировку с этим синтаксисом в моей модели Group, в которой много пользователей через group_users:

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

Настройте код в соответствии с вашими потребностями, который будет работать.

2 голосов
/ 16 января 2013

Вы также можете создать новый столбец 'sort_order' в таблице назначений и добавить область по умолчанию, например

default_scope { order('sort_order desc')}

к вашей модели назначений.

0 голосов
/ 16 апреля 2019

has_many: пользователи, -> {order (: last_name,: first_name)},: through =>: назначения, источник: 'user'

...