2013-03-13 21 views
5

Mam wiele różnych modeli w aplikacji Rails, nad którymi pracuję. Zauważyłem, że wiele witryn korzysta z metody routingu w całej aplikacji. Co mam przez to na myśli?Jak utworzyć routing dla aplikacji Rails w całej aplikacji?

http://example.com/nick-oneill <-- This points to a User object 
http://example.com/facebook <-- This points to a Company object 
http://example.com/developers <-- This points to the users#index page 

Jestem świadomy to_param i tworzenia ślimaki przyjazny dla czytelnika w aplikacjach, jednak nie jestem świadomy podejścia mieć ślimaki korzeń szczebla z różnych przedmiotów. Możesz myśleć, że jest podobny do interfejsu Graph API Graph: istnieją różne typy obiektów, ale wszystkie one istnieją pod adresem: https://graph.facebook.com/object-id

Wszelkie informacje są mile widziane!

+0

hmm. Prawdopodobnie masz stół ze ślimakami, w którym trzymasz taki typ. następnie dodaj trasę, która sprawdza ten typ i spróbuj przekierować na podstawie tego. – jvnill

+0

To wydaje się nieco przesadzone, ponieważ teraz muszę wykonać dwie prośby o pobranie obiektu, nie? –

+0

to jest.Nie wiem, w jaki sposób szyny rozróżniają ślimaki, chyba że są już zdefiniowane lub przynajmniej mają jakiś wzór, który może je rozróżnić. – jvnill

Odpowiedz

10

Może istnieć sposób na zrobienie tego za pomocą atrybutu freindly_id, ale myślę, że problem z przyjaznym identyfikatorem jest zgodny z modelem.

Gdybym chciała naprawdę sutek z boku, utworzyłbym stół ślimakowy z polimorficznym stosunkiem do wszystkich moich modeli.

Sluggable_type and sluggable_id, a następnie pole slug z pełnym permalinkiem/slugem.

+---------------------------------------------+ 
| sluggable_type | sluggable_id |  slug | 
|  user  |  13  | users/john | 
+---------------------------------------------+ 

Teraz mogłem zrobić zrobić asterisk złapać wszystkie trasy lub stworzyć trasy dla wszystkich moich ślimaki przy starcie i wymusić odświeżenie trasach gdy model jest aktualizowany, który był pod tym sluggable kontrolą.

routes.rb

get "/*segments", 
       :controller => 'slugs', 
       :action => 'dynamicroute' 

Teraz w SlugsController zaimplementować metody takie jak

def dynamicroute 
    segments = params[:segments] 
    slugs.find_by_slug(segments) 
    slug.sluggable_type.constantize.find(slug.sluggable_id) #retrive real record 
    #some magic to handle the slugged item maybe redirect to the appropriate 
    #controller or somehow call the show view for that controller 
end 

LUB

routes.rb

begin 
    Slug.all.each do |s| 
    begin 
     get "#{s.slug}" => "#{s.sluggable_type.demodulize.pluralize.camelize}#show" 
    rescue 
    end 
    end 
rescue 
end 

Jeśli użyć 2nd podejście do routingu upewnić zadzwonić

YOUR_APP_NAME::Application.reload_routes!

Po edycji dowolnego slugged rekord odświeżyć tabelę routingu.

Mieliśmy podobne problemy i możemy wypróbować naszych narzędzi w tym zakresie.

+0

Cholera, pokonaj mnie do podobnej odpowiedzi podczas pisania. Wygląda na to, że twoje podejście do routingu może być bardziej przemyślane niż moje naiwne. – imakewebthings

+0

używamy go w produkcji, ale tylko dla stron, ale myślę, że powinien skalować się w ten sposób? To miłe, ponieważ widzisz wszystkie swoje wytyczone trasy w "trasach rake'owych" –

+0

@j_mcnally, używasz pierwszej lub drugiej wersji w produkcji? Druga metoda wygląda na WAYYYY czystsze. Staje się dość brudny, kiedy muszę załadować kolejny kontroler z metody kontrolera. Jedyny wyjątek, który moim zdaniem mógłby potencjalnie stworzyć pośredniczący kontroler o nazwie SluggedController, który podklasy ApplicationController, a następnie podklasę SluggedController dla innych kontrolerów. Ciekawy, żeby tu zebrać myśli! –

2

I pewnie zbliżyć się to w następujący sposób, przynajmniej w pierwszym przejściu:

  • Zastosowanie friendly_id lub podobny do generowania ślimaki dla każdego modelu zaangażowanych
  • Podłącz catch-all i trasy dla /([-_a-zA-Z0-9]+) skierować go do czegoś podobnego EntitiesController#show
  • Podłącz większą trasą priorytetowy /developers skierowaną do Users#index
  • W EntitiesController # show:

    @entity = User.find(params[:id]) or Company.find(params[:id]) or raise ActionController::RoutingError.new('Not Found')

  • Następnie, w zależności od rodzaju podmiotu już otrzymała:

    render "VIEW_PATH_BASED_ON_ENTITY_CLASS/show"

Chciałbym również zamówić znaleziska od najbardziej do najmniej często dostępne (Chyba pierwszy , następnie użyj danych później, aby poprawić kolejność).

Na koniec, prawdopodobnie jest to oczywiste, ale upewnij się, że indeksujesz kolumnę ślimaka w każdej tabeli, ponieważ często robisz wiele znalezień dla każdego żądania.

FWIW Chciałbym poznać lepszy sposób podejścia do tego zagadnienia; to jest po prostu sposób, w jaki najpierw zaatakowałbym problem.

+0

Dzięki za notatkę Kyle! Przegrałem twoją odpowiedź, ale czekam, aby zobaczyć, co jeszcze otrzymam ... próbując znaleźć najlepsze podejście tutaj :) –

0

Moja pierwsza reakcja to utworzenie nowego modelu ślimaka. Model ten miałby polimorficzny belongs_to:

belongs_to :sluggable, :polymorphic => true 

Przynajmniej tabela ta musiałaby:

  • value - albo jakąś lepszą nazwę niż ten. Wartość samego ślimaka.
  • sluggable_type i sluggable_id - Polimorficzne klucze obce.

firmy, użytkowników itp modele Modele po prostu mieć ślimak:

has_one :slug 

To daje nam kilka zalet przy bat:

  • To teraz łatwo zrobić unikalne ograniczenie dla wartości granicznej. Jeśli ślimak był trzymany jako własność wszystkich różnych modeli, więc twoje unikalne ograniczenie musiałoby sprawdzić wszystkie inne tabele, które by były wyjątkowe. Sprawia, że ​​jest zły czas.
  • Trasowanie jest dość proste, ponieważ możesz korzystać z normalnej trasy resource poza obszarem nazw poziomu głównego. Będziesz chciał zachować niski/na końcu pliku trasy, chociaż pierwszeństwo mają inne, bardziej szczegółowe trasy. Edytuj: Ta rutowanie jest po prostu pierwszą metodą rutowania j_mcnally sugeruje.
  • Cała logika ślimaka, jak to, co tworzy ważny ślimak, jest przechowywana w tym jednym modelu. Dobre rozdzielenie obaw zamiast zanieczyszczania oznacza model użytkownika. Zwłaszcza, jeśli zasady dotyczące ślimaków są takie same dla wszystkich, jak tutaj.

W kategoriach jak regulator będzie działać, pójdę z tym, co powiedział Kyle i klucz off dziedzinie sluggable_type znaleźć widok, który chcesz renderowania.