2010-02-05 12 views
51

Biorąc pod uwagę następujące modele AR, chciałbym uporządkować użytkowników alfabetycznie według nazwiska, gdy dany uchwyt do zadania:Jak mogę zamówić has_many przez asocjację w Ruby on Rails?

chciałbym dostać zadanie następnie nawigację do wyznaczonych użytkowników, i porządek lista użytkowników alfabetycznie.

Ciągle myślę, że powinienem być w stanie dodać klauzulę :order do has_many :users, :through => :assignments tak:

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

jednak to nie działa.

Jak mogę posortować użytkowników według last_name po przydzieleniu zadania?

Odpowiedz

7

Czy ta praca jest dla Ciebie?

# User.rb 

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

Można zdefiniować inne nazwane zakresy, gdy sortowanie musi być inne.

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

+2

Przepraszam, że podskakuję stare pytanie, ale może to być istotne dla przyszłych czytelników: Niektóre wtyczki (act_as_list na przykład) nie działają poprawnie z default_scope. – robinjam

+0

Również podskakuję, ponieważ miałem podobny problem, ale trzeba było posortować na polu W tabeli: - niesamowitą rzeczą jest to, że default_scope działa również w: przez tabelę, a rekordy pobierane za pośrednictwem tej relacji będą respektować zamówienie. – MBHNYC

36

Szyny wersji 3.x:

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

UPDATE: Działa to tylko w szynach 3.x (być może wcześniej, że zbyt). Dla 4+ zobacz inne odpowiedzi.

+0

Działa również dla mnie. Czyste rozwiązanie, które nie ma wpływu na inne funkcje posortowanego modelu, jak ma to miejsce w pierwszej odpowiedzi. – barancw

+2

nie działa, mówi: zamówienie nie jest kluczem. Poniżej znajduje się odpowiedź narzędzia Denial IS. – RohitPorwal

12

Podejście M.G.Palmer's działa dobrze, jednak nazwa tabeli jest zaangażowana. Nie ma lepszego sposobu, aby to zrobić:

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

, ale co, jeśli kolejność jest określona przez tabelę łączyć? na przykład przypisania ... ale bez definiowania domyślnego zakresu przy zadaniach .. – Tilo

2

Można również utworzyć nowy „” porządek_sortowania kolumnę tabeli przypisania i dodać domyślny zakres jak

default_scope { order('sort_order desc')} 

do modelu przypisań.

65

Ponieważ argumenty stan są przestarzałe w Rails 4, należy stosować zakres bloki:

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

Wygląda na to, że obecnie jest błąd w Railsach 4 z tym https://github.com/rails/rails/issues/17904 "W Rails 4.0, klauzula zleceń została zignorowana, w Rails 4.1 generowany jest niepoprawny SQL. " – Nate

+0

To nawet nie daje mi tego, po prostu całkowicie ignoruje klauzulę zamówienia bez wiadomości. –

6

Działa to dla mnie (Rails 4.2)

stosując kolejność na przelotowych mapie nie jest zachowana, aka to nie wystarczy mieć gatunki nakazał:

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 

Więc nadpisać to na przykład:

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

Aby dokonać tej pracy dla zadań, powinno to być coś takiego (niesprawdzone)

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 
2

Używam szyn (5.0.0.1) i może sprawić, że z tego rodzaju składni w moim modelu Grupy, ma wielu użytkowników poprzez group_users:

Dostosuj kod do swoich potrzeb, które będą działać.

Powiązane problemy