Подтвердить что ты не робот

Как я могу заказать has_many через объединение в Ruby on Rails?

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

4b9b3361

Ответ 1

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

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

Ответ 2

Rails версия 3.x:

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

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

Ответ 3

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

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

Ответ 5

Это работает для меня (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

Чтобы выполнить эту работу для назначений, это должно быть что-то вроде этого (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

Ответ 6

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

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

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

Ответ 7

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

default_scope { order('sort_order desc')}

к вашей задаче.

Ответ 8

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