Rails-połączenie z, trasami i zagnieżdżonymi zasobami
Ponieważ moje zrozumienie zagnieżdżonych zasobów, na krawędziach szyn, nie powinno
link_to 'User posts', @user.posts
Wskaż
/users/:id/posts
?
Trasy.plik rb zawieramap.resources :users, :has_many => :posts
Jeśli nie jest to zachowanie domyślne, czy można to osiągnąć robiąc coś innego?
4 answers
W tych samych liniach co Rishav:
link_to "User Posts", [@user, :posts]
Oto Wyjaśnienie z mojego bloga.
Naprawdę wcześnie na Railach, piszesz trasy w ten sposób:
redirect_to :controller => "posts", :action => "show", :id => @post.id
To, co zrobi, to posłuszne przekierowanie do show
akcji wewnątrz PostsController
i przejście wzdłuż id
parametru z
wartość whatever @post.id
zwraca. Typowa odpowiedź 302.
Potem pojawił się Rails 1.2 i pozwolił ci używać pomocników routingu, takich jak to:
redirect_to post_path(@post)
I lud się ucieszył.
To zrobiłoby dokładnie to samo. post_path
tutaj zbudowalibyśmy trasę używając @post
obiektu, który wyglądałby jak coś
jak /posts/1
, a następnie redirect_to
odeśle odpowiedź 302 na tę trasę, a przeglądarka podąży za nią.
Potem późniejsze wersje (nie pamiętam która), zezwalały na składnię w ten sposób:
redirect_to @post
I ludzie radowali się po raz drugi.
Magia, ale nie naprawdę
Każda wystarczająco zaawansowana technologia jest nie do odróżnienia od magii.Chociaż to wydaje się magiczne, to nie jest. To, co to robi, jest naprawdę bardzo, bardzo schludne. Metoda
redirect_to
, podobnie jak jej kuzyni link_to
i form_for
, używają wspólnej metody do budowania adresów URL, zwanej url_for
. Metoda url_for
zajmuje wiele różnych
odmiany obiektów, takie jak ciągi znaków, skróty, a nawet instancje modeli, jak w powyższym przykładzie.
Co robi z te obiekty, więc, jest dość schludny. W przypadku wywołania redirect_to @post
powyżej, sprawdza @post
obiekt, widzi, że jest obiektem klasy Post
(Zakładamy, tak czy inaczej) i sprawdza, czy obiekt ten został utrzymany w
baza danych gdzieś przez wywołanie persisted?
na nim.
Przez "persisted" mam na myśli, że obiekt Ruby ma gdzieś pasujący rekord w bazie danych. Metoda persisted?
W Active Record jest zaimplementowana w następujący sposób:
def persisted?
!(new_record? || destroyed?)
end
Jeśli obiekt nie został utworzony przez wywołanie takie jak Model.new
wtedy nie będzie to nowy rekord, a jeśli nie było wywołanej metody destroy
to nie będzie
zniszczone. Jeśli oba te przypadki są prawdziwe, to oznacza to, że obiekt został najprawdopodobniej zapisany do bazy danych w formie rekordu.
Jeśli został utrzymany, to url_for
wie, że obiekt ten można znaleźć
gdzieś, i że miejsce, które można znaleźć jest najprawdopodobniej pod metodą o nazwie post_path
. Więc nazywa tę metodę i przekazuje
w wartość to_param
tego obiektu, która zwykle jest id
.
Krótko mówiąc, skutecznie to robi:
#{@post.class.downcase}_path(@post.to_param)
Co wychodzi na to:
post_path(1)
A gdy ta metoda zostanie wywołana, otrzymasz taki mały ciąg znaków:
"/posts/1"
Cudownie!
Nazywa się to routingiem polimorficznym. Możesz przekazać obiekt metodom takim jak redirect_to
, link_to
i form_for
i będzie
spróbuj ustalić poprawny adres URL tego, czego używać.
The forma formula_for
Teraz, kiedy kodujesz Rails, mogłeś użyć form_for
w ten sposób bardzo dawno temu:
<% form_for @post, :url => { :controller => "posts", :action => "create" } do |f| %>
Oczywiście, z postępami w Rails można uprościć to do tego:]}
<% form_for @post, :url => posts_path do |f| %>
Ponieważ formularz domyślnie będzie miał metodę HTTP POST
i dlatego żądanie do {[46] } trafi do
create
działanie PostsController
, a nie działanie index
, co miałoby wynik, gdyby było to żądanie GET
.
But why stop tam? Dlaczego po prostu tego nie napiszesz?
<%= form_for @post do |f| %>
Osobiście nie widzę powodu, by tego nie robić... jeśli to coś tak prostego jak to. Metoda form_for
używa url_for
pod spodem, tak jak
redirect_to
aby ustalić, gdzie powinien pójść formularz. Wie, że obiekt @post
należy do klasy Post
(ponownie Zakładamy) i
sprawdza, czy obiekt jest utrzymywany. Jeśli tak, to użyje post_path(@post)
. Jeśli nie, to posts_path
.
Sama metoda form_for
sprawdza, czy przekazany obiekt jest a jeśli tak, to domyślnie będzie to PUT
HTTP
metoda, inaczej a POST
.
W ten sposób form_for
Może być wystarczająco elastyczny, aby mieć identyczną składnię zarówno w widoku new
, jak i {63]}. Staje się coraz bardziej i
bardziej powszechne w dzisiejszych czasach, aby ludzie nawet umieścić swoje całe form_for
tagi w jednym częściowym i włączyć go zarówno w new
i
edit
stron.
Bardziej złożona forma
Więc form_for
jest dość proste, gdy mijasz normalny obiekt, ale co się stanie, jeśli miniesz tablicę obiektów? W ten sposób, dla
instancja:
<%= form_for [@post, @comment] do |f| %>
Cóż, zarówno url_for
jak i form_for
też się tym zająłeś.
Metoda url_for
wykrywa, że jest to tablica i oddziela każdą część i sprawdza ją indywidualnie. Po pierwsze, co to jest
Coś? W tym przypadku Załóżmy, że jest to Post
instancja, która jest i ma id 1. Po drugie, co to jest
@comment
obiekt? Jest to instancja Comment
, która nie została jeszcze / align = "left" /
Co url_for
zrobi tutaj, to zbuduje metodę pomocniczą URL kawałek po kawałku, umieszczając każdą część w tablicy, łącząc ją w metodę routingu, a następnie wywołując tę metodę routingu z niezbędnymi argumentami.
Po pierwsze, wie, że obiekt @post
należy do klasy Post
i jest utrzymywany, dlatego helper URL rozpocznie się od post
. Po drugie wie, że obiekt @comment
należy do klasy Comment
i jest Nie i dlatego comments
będzie podążać post
w kompilacji pomocniczej adresu URL. Części, które url_for
teraz wie o [:post, :comments]
.
Metoda url_for
łączy te poszczególne części z podkreśleniem, tak że staje się post_comments
, a następnie dodaje _path
do końca, co daje post_comments_path
. Następnie przechodzi tylko w obiektach do wywołania tej metody, co skutkuje wywołaniem takim jak: {116]}
post_comments_path(@post)
Wywołanie tej metody skutkuje następująco:
"/posts/1/comments"
Najlepsza część? form_for
will nadal wiem, aby używać POST
, jeśli @comment
obiekt nie jest trwałym obiektem, i PUT
, jeśli jest. Dobry
należy pamiętać, że form_for
jest zawsze dla ostatniego obiektu określonego w tablicy. Obiekty przed nim są tylko jego
gniazdowanie, nic więcej.
Im więcej obiektów zostanie dodanych, tym więcej razy url_for
zrobi twarde podwórka i zbuduje ścieżkę... chociaż polecam
trzymaj to tylko w dwóch częściach.
Forma symboliczna
Teraz, że omówiliśmy użycie tablicy zawierającej obiekty dla form_for
, przyjrzyjmy się innemu powszechnemu użyciu. Tablica zawierająca
co najmniej jeden obiekt symbolu, taki jak ten:
<%= form_for [:admin, @post, @comment] do |f| %>
To, co robi tutaj metoda url_for
jest bardzo proste. Widzi, że istnieje Symbol
i przyjmuje to tak, jak jest. Pierwsza część
url
będzie po prostu tym samym symbolem: admin
. Adres URL, który url_for
zna w tym momencie, to po prostu [:admin]
.
Następnie url_for
przechodzi przez pozostałe części tablicy. W w tym przypadku, Załóżmy, że zarówno @post
, jak i @comment
są utrzymane
i że mają ID odpowiednio 1 i 2. Te same zajęcia co wcześniej. url_for
następnie dodaje post
do adresu URL, który buduje,
i comment
również, w wyniku [:admin, :post, :comment]
.
Następnie następuje połączenie, w wyniku czego powstaje metoda admin_post_comment_path
, a ponieważ zarówno @post
, jak i @comment
są tutaj,
są one przekazywane w wyniku wywołania tej metody:
admin_post_comment_path(@post, @comment)
Który (zazwyczaj) zamienia się w to ścieżka:
/admin/posts/1/comments/2
Możesz użyć tablicy w postaci trasowania polimorficznego z redirect_to
, link_to
i form_for
metody. Jest chyba inny
metody, których teraz nie pamiętam, też mogą to zrobić... ogólnie rzecz biorąc, to wszystko w Rails, które normalnie przyjmowałoby adres URL.
Nie ma potrzeby budowania adresów URL w dowolnej wersji Rails większej niż 2 używając hashów; to dość stara szkoła.
Zamiast tego, eksperymentuj z nową wiedzą o routingu polimorficznym i wykorzystaj to jak najlepiej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 04:25:50
To powinno zadziałać:
link_to "User Posts", user_posts_path(@user)
Więcej szczegółów na stronie:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-10 14:06:37
link_to
zastosowania url_for
które wykorzystuje polymorphic_url
.
polymorphic_url
:
-
Buduje metodę pomocniczą , używając nazwy klasy obiektów active record
-
Wywołanie helpera {[9] } z obiektami active record jako argumentami
Dlatego, jak mówili inni, powinieneś użyć:
link_to 'User Posts', [@user, :posts]
Dla którego ścieżka jest:
user_posts_path(@user)
^^^^ ^^^^^ ^^^^^
1 2 3
- Klasa
@user
ponieważ jest rekordem aktywnym - Konwertuj Na string ponieważ symbol
- Dodaj jako argument wywołania, ponieważ active record
To buduje dobrą metodę pomocniczą.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-09 11:53:07
Oto jak połączyć się z zagnieżdżonym zasobem w najnowszych Rails:
Link_to 'Destroy Comment', post_comment_path (comment.post, komentarz)
Uwaga: Jest to częściowe, więc nie ma @
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-09 17:11:48