9

En mi aplicación Rails tengo dos modelos que están relacionados por has_and_belongs_to_many. Esto significa que hay una tabla de unión.Pedido de has_and_belongs_to_many associations

Imagine el escenario en el que agrego usuarios a un juego. Si quiero agregar un usuario, que hago:

@game.users << @user 

Suponiendo que yo quiero saber en qué orden añadí estos usuarios. Puedo hacer esto:

@game.users.each do.... 

Mis preguntas son:

  1. es el ordenamiento si esta lista garantizada para leer de la misma manera cada vez?

  2. Si ese es el caso, ¿cuál es una forma limpia de reordenar a los usuarios en el juego?

Respuesta

18

para ampliar el fondo de la respuesta de danivo:

Si usted quiere pedir por el momento de su incorporación a esta lista, entonces te recomiendo que en vez de utilizar un has_and_belongs_to_many que realmente utiliza un has_many :through:

game.rb

has_many :played_games 
has_many :users, :through => :played_games, :order => "played_games.created_at ASC" 

user.rb

has_many :played_games 
has_many :games, :through => :played_games 

played_game.rb

belongs_to :game 
belongs_to :user 

Por supuesto, los cambios pendientes en los nombres ...

En los played_games tabla si usted tiene una columna llamada created_at la segunda has_many en los juegos ordenará por este campo y devolverá a los usuarios en el orden en que se agregaron al juego.

+0

Creo que esto puede funcionar para mí ... para dar más contexto. No necesito ordenar por nombre de usuario, sino que quiero que el servidor elija un orden al azar para que las posiciones de los jugadores en el juego sean decididas por él. Así que supongo que puedo poner un campo 'player_index' en la tabla played_game, y proporcionar índices en el punto en el que quiero decidir quién se mueve primero ... – cmaughan

11

No estoy seguro, pero yo diría que el orden es el garantizado a ser el mismo que su base de datos garantiza el orden del conjunto de resultados sin una orden por cláusula.

Puede agregar :order => "last_name, first_name asc" a la declaración de la relación :has_and_belongs_to_many. Esto establecerá un comportamiento predeterminado para el orden de los elementos que vuelve.

También puede hacer @game.users.find(:all, :order => "last_name, first_name asc") o crear ámbitos con nombre para el pedido común que necesitará. Check out the api for details

Si conocer el orden que los agregó es realmente importante, es probable que desee cambiar a una relación has_many :through para que la tabla de unión tenga una entidad propia. Luego tendrá una marca de tiempo created_on y updated_on para esa relación administrada por rails.

+0

El estándar SQL explícitamente no dice nada sobre ordenar.Por lo general, es el orden de creación porque así es como se recogen los registros cuando se ensamblan los conjuntos de resultados, pero eso es solo una coincidencia. Una base de datos que ha tenido muchas actualizaciones puede tener registros por todos lados. Orden del usuario si es importante Me quemó en Rails con #last devolviendo cosas diferentes para postgres. – Ghoti

Cuestiones relacionadas