2009-03-31 3 views
8

Powiedz, że mam aplikację szyn z 3 modelami, osobą, miejscem i rzeczą. Say the Thing używa dziedziczenia pojedynczej tabeli, więc istnieją podklasy FancyThing i ScaryThing. Następnie są zdefiniowane trasy z map.resources :people, :places, :things. Więc nie ma kontrolerów dla FancyThings i ScaryThings, The ThingsController obsługuje oba typy.Uzyskaj trasę do klasy bazowej klasy STI w szynach

Teraz mów, że muszę mieć kod, który pokazuje listę czegokolwiek ma do nich linki. Jeśli mam ten kod w moim zdaniem:

<% @items.each do |item| %> 
    <%= link_to item.name, item %> 
<% end %> 

Jeśli pozycja jest osoba lub miejsce, to działa prawidłowo, polymorphic_path dba wygenerowania poprawną trasę. Ale jeśli przedmiot jest FancyThing lub ScaryThing, to wieje, bo będzie próbował użyć fancy_thing_path, do którego nie ma trasy. Chcę w jakiś sposób użyć go thing_path. Idealnie byłoby na Thing i/lub jej podklasach metoda, która jakoś wskazuje, że podklasy powinny używać klasy bazowej do generowania trasy. Czy istnieje na to eleganckie rozwiązanie?

+0

To jest [otwarty bilet] (http://dev.rubyonrails.org/ticket/10454) na tworzenie szyn. Zobacz bilet na sugestie, jak sobie z tym poradzić. – MarkusQ

Odpowiedz

12

Ten rade:

<% @items.map {|i| if i.class < Thing then i.becomes(Thing) else i end}.each do |item| %> 
    <%= link_to item.name, item %> 
<% end %> 

ta wykorzystuje funkcję ActiveRecord „staje się” zrobić "Up-cast" wszystkich podklas klasy Thing do klasy podstawowej Thing.

+0

Dobrze, nie wiedziałem o tym, dzięki, dzięki! – pjb3

+0

To rozwiązanie jest około 10 razy tak eleganckie, jak się spodziewałem. –

8

Spróbuj użyć

map.resources :things 
map.resources :fancy_things, :controller => 'things' 
map.resources :scary_things, :controller => 'things' 
+1

+1 Z dwóch powodów 1) To działa dla mnie. 2) Ta odpowiedź wygląda na bardziej suchą niż ta zaakceptowana przez @ pjb3. Dzięki. – Rohit

+0

To rozwiązanie działa, ale ma wadę, która nie wymusza klasy/typu, np. jeśli zapytasz o identyfikator za pośrednictwem http: // localhost: 3000/fancy_things/21 i ten element jest faktycznie z innej podkategorii ScaryThings, nadal otrzymasz poprawną odpowiedź. Powinien faktycznie dać błąd, ponieważ nie jest to klasa FancyThings. – Tilo

0

Nie masz poprawną odpowiedź, ale przynajmniej mogę poradzić sobie z tym problemem za pomocą kodu nie wyschnąć:

map.resources: rzeczy: has_many => : Produkty spożywcze map.resources: fancy_things,: controller => 'rzeczy',: has_many =>: Produkty spożywcze map.resources: scary_things,: controller => 'rzeczy',: has_many =>: Produkty

Hope Problem wkrótce zostanie poprawiony, ponieważ chciałbym to zobaczyć fancy_things zarządza tylko przez: kontroler rzeczy. Korzystanie z tych tras, skończy z adresów URL, takich jak:/fancy_things/1, podczas gdy ty może chcesz/rzeczy/1