ruby-on-rails - inverse_of - rails references
¿Cómo ordeno una asociación de has_many en Ruby on Rails? (7)
Dado los siguientes modelos de RA, me gustaría ordenar los usuarios alfabéticamente por apellido cuando se les da un manejador para una tarea:
#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
Me gustaría obtener una tarea y luego navegar a los usuarios asignados, y ordenar la lista de usuarios alfabéticamente .
Sigo pensando que debería ser capaz de agregar la cláusula :order
a has_many :users, :through => :assignments
como esta:
#task.rb
has_many :assignments
has_many :users, :through => :assignments, :order => ''last_name, first_name''
sin embargo, esto no funciona.
¿Cómo puedo clasificar a los usuarios por last_name
cuando se les asigna una tarea?
Dado que los argumentos de condición están en desuso en Rails 4, uno debe usar bloques de alcance:
has_many :users, -> { order ''users.last_name, users.first_name'' }, :through => :assignments
El MGPalmer''s
funciona bien, sin MGPalmer''s
nombre de la tabla. Hay una mejor manera de hacerlo:
has_many :users, :through => :assignments, :order => [ :last_name, :first_name ]
Esto funciona para mí (Rails 4.2)
No se conserva la aplicación de un pedido en el mapa directo, también conocido como esto no es suficiente para ordenar los géneros:
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
Así que sobrescribo esto por instancia:
def genres # redefine genres per instance so that the ordering is preserved
self.disk_genre_maps.map{|dgm|dgm.genre}
end
Para hacer que eso funcione para las asignaciones, esto debería ser algo como esto (no probado)
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
Estoy usando Rails (5.0.0.1) y podría hacer la ordenación con esta sintaxis en mi modelo Grupo que tiene muchos usuarios a través de group_users:
# Associations.
has_many :group_users
has_many :users, -> { order(:name) }, through: :group_users
Ajuste el código a su necesidad que funcionará.
Que este trabajo para usted?
# User.rb
class User < ActiveRecord::Base
default_scope :order => ''last_name ASC''
...
end
Puede definir otros ámbitos nombrados para cuando la ordenación necesite ser diferente.
http://ryandaigle.com/articles/2008/11/18/what-s-new-in-edge-rails-default-scoping
También podría crear una nueva columna ''sort_order'' en la tabla de asignaciones y agregar un alcance predeterminado como
default_scope { order(''sort_order desc'')}
a su modelo de asignaciones.
Versión de Rails 3.x:
has_many :users, :through => :assignments, :order => ''users.last_name, users.first_name''
ACTUALIZACIÓN: Esto solo funciona en Rails 3.x (quizás antes de eso también). Para 4+, vea otras respuestas.