Przeglądam przewodnik Pierwsze kroki z Railsami i pomyliłem się z sekcją 6.7. Po wygenerowaniu rusztowania znajduję w moim kontrolerze następujący automatycznie wygenerowany blok:
def index
@posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @posts }
end
end
Chciałbym zrozumieć, jak faktycznie działa blok respond_to. Jakim typem zmiennej jest format? Czy metody .html i .json obiektu formatu są? Dokumentacji dla
ActionController::MimeResponds::ClassMethods::respond_to
nie odpowiada na pytanie.
ruby-on-rails
Kapusta
źródło
źródło
format.html
- bez argumentu), użyje konwencji (na podstawie adresu URL i czasownika HTTP), aby wybrać widok (prawdopodobnie HTML). Obiekt odpowiadający (format) jest tutaj instruowany, aby renderował adresy URL kończące się na .json przez serializację do json, zamiast używania widoków i konwencji.Odpowiedzi:
Jestem nowy w Ruby i utknąłem na tym samym kodzie. Części, na których się rozłączyłem, były trochę bardziej fundamentalne niż niektóre odpowiedzi, które tu znalazłem. To może, ale nie musi komuś pomóc.
respond_to
jest metodą nadklasyActionController
.do
doend
, z|format|
argumentem do bloku.format
argumentu.http://api.rubyonrails.org/v4.1/classes/ActionController/Responder.html
Responder
Nie zawiera metodę.html
albo.json
, ale nazywamy tych metod anyways! Ta część rzuciła mnie na pętlę.method_missing
. Jeśli wywołasz metodę, która nie istnieje (jakjson
lubhtml
), Rubymethod_missing
zamiast niej wywołuje metodę.http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html
Responder
Klasa wykorzystujemethod_missing
jako rodzaj rejestracji. Kiedy nazywamy „json”, mówimy mu, aby odpowiadał na żądania z rozszerzeniem .json, serializując do json. Musimy zadzwonićhtml
bez argumentów, aby nakazać mu obsługę żądań .html w domyślny sposób (przy użyciu konwencji i widoków).Można to napisać w ten sposób (używając pseudokodu podobnego do JS):
Ta część mnie zdezorientowała. Nadal uważam to za nieintuicyjne. Ruby wydaje się używać tej techniki dość często. Cała klasa (
responder
) staje się implementacją metody. Aby wykorzystać dźwignięmethod_missing
, potrzebujemy instancji klasy, więc jesteśmy zobowiązani do przekazania wywołania zwrotnego, do którego przekazują obiekt podobny do metody. Dla kogoś, kto koduje w językach podobnych do C od 20 lat, jest to dla mnie bardzo zacofane i nieintuicyjne. Nie to, że jest źle! Ale jest to coś, co wielu ludzi z takim doświadczeniem musi się rozejrzeć, i myślę, że może być tym, o co chodziło OP.ps zauważyć, że w RoR 4.2
respond_to
został wyodrębniony w klejnot odpowiedzi .źródło
method_missing
, biorąc pod uwagę, że można przekazać argumenty i blok!respond_to
w kontrolerach, bez klejnotu odpowiadającego w Gemfile. Być może zmieniono niecorespond_to
kwestię bycia wyodrębnionym do klejnotu respondentów?Jest to blok kodu Ruby, który korzysta z metody pomocniczej Rails. Jeśli nie znasz jeszcze bloków, zobaczysz je bardzo często w Ruby.
respond_to
jest metodą pomocniczą Rails, która jest dołączona do klasy Controller (a raczej jej superklasy). Odnosi się do odpowiedzi, która zostanie wysłana do Widoku (który przechodzi do przeglądarki).Blok w twoim przykładzie to formatowanie danych - poprzez przekazanie parametru „format” w bloku - wysyłanego z kontrolera do widoku, ilekroć przeglądarka wysyła żądanie danych HTML lub JSON.
Jeśli korzystasz z komputera lokalnego i masz skonfigurowane rusztowanie Post, możesz przejść do,
http://localhost:3000/posts
a zobaczysz wszystkie swoje posty w formacie HTML. Ale jeśli wpiszeszhttp://localhost:3000/posts.json
to:, zobaczysz wszystkie swoje posty w obiekcie json wysłanym z serwera.Jest to bardzo przydatne do tworzenia ciężkich aplikacji javascript, które muszą przesyłać json tam iz powrotem z serwera. Jeśli chcesz, możesz łatwo utworzyć interfejs json api na zapleczu szyn i przekazać tylko jeden widok - na przykład widok indeksu kontrolera Post. Następnie możesz użyć biblioteki javascript, takiej jak Jquery lub Backbone (lub obie), aby manipulować danymi i utworzyć własny interfejs. Są to tak zwane asynchroniczne interfejsy użytkownika i stają się bardzo popularne (Gmail jest jednym z nich). Są bardzo szybkie i zapewniają użytkownikowi końcowemu bardziej wrażenia z korzystania z komputera w Internecie. Oczywiście jest to tylko jedna zaleta formatowania danych.
Sposób pisania w Rails 3 byłby następujący:
Umieszczając
respond_to :html, :xml, :json
na szczycie klasy, możesz zadeklarować wszystkie formaty, które kontroler ma wysyłać do twoich widoków.Następnie w metodzie kontrolera wszystko, co musisz zrobić, to odpowiedz_z (@wszystko_obiektywem_masz)
To tylko upraszcza twój kod nieco bardziej niż to, co Rails generuje automatycznie.
Jeśli chcesz wiedzieć o wewnętrznym funkcjonowaniu tego ...
Z tego, co rozumiem, Railsy introspekują obiekty, aby ustalić, jaki będzie rzeczywisty format. Wartość zmiennych „format” opiera się na tej introspekcji. Szyny mogą wiele zrobić z odrobiną informacji. Byłbyś zaskoczony, jak daleko posunie się prosty @post lub: post.
Na przykład, jeśli mam plik częściowy _user.html.erb, który wyglądałby tak:
_user.html.erb
Wtedy to samo w moim widoku indeksu dałoby Railsom informację, że trzeba znaleźć częściowe „użytkowników” i iterować przez wszystkie obiekty „użytkowników”:
index.html.erb
poinformuje Railsów, że musi znaleźć częściowe „użytkownika” i iterować przez wszystkie obiekty „użytkowników”:
Ten post może być przydatny: http://archives.ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with
Możesz także przejrzeć źródło: https://github.com/rails/rails
źródło
respond_to
irespond_with
wprowadził? Używam szyn 2.3.5 i dostajęNoMethodError (undefined method respond_to)
Z tego co wiem, respond_to jest metodą dołączoną do ActionController, więc możesz używać jej w każdym kontrolerze, ponieważ wszystkie dziedziczą po ActionController. Oto metoda Rails respond_to:
Mijasz blok , jak pokazuję tutaj:
| Format | część jest argumentem, którego oczekuje blok, więc w metodzie respond_to możemy tego użyć. W jaki sposób?
Cóż, jeśli zauważysz, że przekazujemy blok z prefiksem & w metodzie respond_to i robimy to, aby traktować ten blok jako Proc. Ponieważ argument zawiera „.xml”, „.html”, możemy go użyć jako metody do wywołania.
W zasadzie robimy w klasie respond_to metody wywoływania „.html, .xml, .json” do instancji klasy obiektu odpowiadającego.
źródło
Aby zrozumieć, co to
format
jest, możesz najpierw spojrzeć na źródłorespond_to
, ale szybko przekonasz się, że tak naprawdę musisz przyjrzeć się kodowi retrieve_response_from_mimes .Stąd zobaczysz, że blok, który został przekazany
respond_to
(w twoim kodzie), jest faktycznie wywoływany i przekazywany z instancją Collector (która w bloku jest oznaczona jakoformat
). Collector generuje metody (jak sądzę przy starcie Railsów) w oparciu o to, o czym wie typy mime .Więc tak,
.html
i.json
są metodami zdefiniowanymi (w czasie wykonywania) w Collector (aliasformat
).źródło
Metaprogramowanie odpowiadające za rejestrację respondentów (patrz odpowiedź Spieczona kałamarnica) pozwala także robić fajne rzeczy:
Linia csv spowoduje, że to_csv będzie wywoływany w każdym poście podczas odwiedzania /posts.csv. Ułatwia to eksportowanie danych jako CSV (lub dowolnego innego formatu) ze strony internetowej.
Wiersz js spowoduje wyświetlenie / wykonanie pliku javascript /posts.js (lub /posts.js.coffee). Odkryłem, że jest to lekki sposób na stworzenie strony obsługującej Ajax przy użyciu wyskakujących okienek interfejsu użytkownika jQuery.
źródło
Z Java POV format jest implementacją anonimowego interfejsu. Ten interfejs ma jedną metodę nazwaną dla każdego typu MIME. Kiedy wywołujesz jedną z tych metod (przekazując mu blok), to jeśli szyny czują, że użytkownik chce tego typu treści, wówczas wywoła twój blok.
Rzecz w tym, że ten anonimowy obiekt kleju w rzeczywistości nie implementuje interfejsu - dynamicznie łapie wywołania metody i sprawdza, czy jest to nazwa typu MIME, o którym wie.
Osobiście uważam, że wygląda to dziwnie: blok, który przekazujesz, jest wykonywany . Bardziej sensowne byłoby dla mnie przekazanie skrótu etykiet formatu i bloków. Ale - tak to wygląda w RoR.
źródło
To jest trochę przestarzałe, Ryan Bigg robi świetną robotę, tłumacząc to tutaj:
http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to
W rzeczywistości może być nieco bardziej szczegółowy niż się spodziewałeś. Jak się okazuje, za kulisami dzieje się wiele, w tym potrzeba zrozumienia, w jaki sposób ładowane są typy MIME.
źródło
„Format” to typ odpowiedzi. Może to być na przykład json lub html. Jest to format wyników, które otrzyma gość.
źródło
Jest jeszcze jedna rzecz, o której powinieneś wiedzieć - MIME.
Jeśli potrzebujesz użyć typu MIME i nie jest on domyślnie obsługiwany, możesz zarejestrować własne programy obsługi w config / initializers / mime_types.rb:
Mime::Type.register "text/markdown", :markdown
źródło