9

W mojej aplikacji rails mam dwa modele powiązane przez has_and_belongs_to_many. Oznacza to, że istnieje tabela łączenia.Zamawianie ma_and_belongs_to_many asocjacji

Wyobraź sobie scenariusz, w którym dodaję użytkowników do gry. Jeśli chcę dodać użytkownika, robię:

@game.users << @user 

Przypuśćmy, że chcę wiedzieć, w jakiej kolejności dodałem tych użytkowników. Mogę to zrobić:

@game.users.each do.... 

moje pytania są następujące:

  1. Czy zamawianie jeśli ta lista gwarantowana czytać w ten sam sposób za każdym razem?

  2. Jeśli tak, to w jaki sposób można zmienić kolejność użytkowników w grze?

Odpowiedz

18

Aby rozwinąć na dnie danivo za odpowiedź:

Jeśli chcesz zamówić w momencie ich dodawania do tej listy to polecam, że zamiast używać has_and_belongs_to_many faktycznie używać 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 

Oczywiście, w oczekiwaniu na zmianę nazw ...

W played_games stół jeśli kolumna nazywa created_at drugi has_many w grach zamówi przez to pole i zwróci użytkowników w kolejności, w jakiej zostali dodani do gry.

+0

Myślę, że to może dla mnie ... dać więcej kontekstu - nie muszę sortować według nazwy użytkownika, raczej chcę, aby serwer losowo wybierał rozkaz, tak aby pozycje gracza w grze były przez niego decydowane. Sądzę więc, że mogę umieścić pole "player_index" w tabeli played_game i podać indeksy w punkcie, w którym chcę zdecydować, kto pierwszy poruszy .... – cmaughan

11

Nie jestem pewien, ale powiedziałbym, że zamówienie jest tak samo gwarantowane, jak twoja baza danych, gwarantuje kolejność zestawów wyników bez klauzuli zamówienia.

Możesz dodać :order => "last_name, first_name asc" do oświadczenia o relacjach :has_and_belongs_to_many. Spowoduje to ustawienie domyślnego zachowania dla kolejności elementów, które wróci.

Można również wykonać @game.users.find(:all, :order => "last_name, first_name asc") lub utworzyć nazwane zakresy do wspólnego porządkowania, które będą potrzebne. Check out the api for details

Jeśli znajomość zamówienia, do którego je dodałeś, jest bardzo ważna, prawdopodobnie chcesz przełączyć się na relację has_many :through, aby tabela dołączeń zawierała jednostkę. Wtedy będziesz mieć znacznik czasu created_on i updated_on dla tej relacji zarządzanej przez szyny.

+0

Standard SQL wyraźnie nie mówi nic o zamawianiu.Zazwyczaj jest to porządek tworzenia, ponieważ w ten sposób rekordy są zbierane podczas składania zestawów wyników, ale to tylko zbieg okoliczności. Baza danych, która miała wiele aktualizacji, może mieć wszystkie rekordy. Zamówienie użytkownika, jeśli jest to ważne. Zostałem spalony w Railsach z #astem zwracającym różne rzeczy za postgreSy. – Ghoti