Aktualizacja dla Rails 4.2+
#respond_with
i ::respond_to
( metoda klasy nb ) nie są już częścią Railsów . Zostały zmigrowane do klejnotu respondentów innych firm od Rails 4.2 ( informacje o wydaniu / zatwierdzenie z sierpnia 2014). Chociaż respondery nie są domyślnie zawarte w Railsach, jest to zależne od Devise, a zatem dostępne w wielu aplikacjach Railsowych.
Jednak #respond_to
metoda instancji jest nadal częścią Railsów (5.2rc1 w chwili pisania tego tekstu).
Oficjalna dokumentacja Rails API ActionController::MimeResponds
wyjaśnia, jak to #respond_to
działa. Oryginalna dokumentacja Rails Guides zawiera komentarze #respond_with
i ::respond_to
nadal można ją znaleźć w kodzie źródłowym gemów responderów .
Oryginalna odpowiedź
Kod odpowiadający jest oparty na klasie i module. MimeResponds, która jest zawarta w ActionController :: Base , klasie, z której ApplicationController
dziedziczy. Następnie jest ActionController :: Responder, który zapewnia domyślne zachowanie podczas korzystania z respond_with.
Domyślnie jedyne zachowanie, które szyny dostarcza w odpowiedzi, to niejawna próba renderowania szablonu o nazwie pasującej do akcji. Cokolwiek poza tym wymaga więcej instrukcji w akcji lub niestandardowego wywołania respond_to z blokiem do obsługi odpowiedzi w wielu formatach.
Ponieważ większość kontrolerów używa dość powszechnego wzorca dostosowywania, respondenci zapewniają dodatkowy poziom abstrakcji, wprowadzając bardziej domyślne zachowanie. Przeczytaj akcje wywołujące to_xml / to_json dla określonych formatów i akcje mutatora zapewniające to samo, a także przekierowania dla udanych akcji mutatora.
Istnieje kilka możliwości dostosowania zachowania respondentów, od subtelnych poprawek po całkowite zastąpienie lub rozszerzenie zachowania.
Poziom klasy: respond_to
Tutaj określasz formaty, które powinien obsługiwać obiekt odpowiadający. Formaty można dostosować do czynności, do których będą się odnosić. Każdy format można określić za pomocą oddzielnych wywołań, co umożliwia pełne dostosowanie działań dla każdego formatu.
# Responds to html and json on all actions
respond_to :html, :json
# Responds to html and json on index and show actions only.
respond_to :html, :json, :only => [:index,:show]
# Responds to html for everything except show, and json only for index, create and update
respond_to :html, :except => [:show]
respond_to :json, :only => [:index, :create, :update]
Poziom klasy: responder
To jest atrybut klasy, który zawiera odpowiadającego. Może to być wszystko, co odpowiada na wywołanie, co oznacza, że możesz użyć proc / lambda lub klasy, która odpowiada na wywołanie. Inną alternatywą jest połączenie jednego lub modułów z istniejącym responderem w celu przeciążenia istniejących metod, zwiększając domyślne zachowanie.
class SomeController < ApplicationController
respond_to :json
self.responder = proc do |controller, resources, options|
resource = resources.last
request = controller.request
if request.get?
controller.render json: resource
elsif request.post? or request.put?
if resource.errors.any?
render json: {:status => 'failed', :errors => resource.errors}
else
render json: {:status => 'created', :object => resource}
end
end
end
end
Chociaż mogą istnieć interesujące przypadki użycia krawędzi, bardziej prawdopodobne jest, że rozszerzanie lub mieszanie modułów do domyślnego respondera byłoby bardziej powszechnymi wzorcami. W każdym razie opcje, które są istotne, to zasoby i opcje, ponieważ są one przekazywane z pliku from respond_with.
Poziom instancji: respond_with
Opcje tutaj to te, które zostaną przekazane do renderowania lub przekierowania w kontrolerze, ale są one uwzględnione tylko w scenariuszach sukcesu. W przypadku akcji GET byłyby to wywołania renderowania, w przypadku innych akcji byłyby to opcje przekierowania. Prawdopodobnie najbardziej użyteczną z nich jest :location
opcja, której można użyć do zastąpienia ścieżki przekierowania w przypadku, gdy argumenty funkcji respond_with nie są wystarczające do zbudowania właściwego adresu URL.
# These two are essentially equal
respond_with(:admin, @user, @post)
respond_with(@post, :location => admin_user_post(@user, @post)
# Respond with a 201 instead of a 200 HTTP status code, and also
# redirect to the collection path instead of the resource path
respond_with(@post, :status => :created, :location => posts_path)
# Note that if you want to pass a URL with a query string
# then the location option would be needed.
# /users?scope=active
respond_with(@user, :location => users_path(:scope => 'active'))
Alternatywnie, reagujący gem nie tylko udostępnia niektóre moduły do nadpisywania niektórych domyślnych zachowań. Zastępuje domyślny responder anonimową klasą, która rozszerza domyślny responder i zapewnia metodę na poziomie klasy do mieszania niestandardowych modułów do tej klasy. Najbardziej przydatny jest tutaj moduł odpowiadający na flash, który zapewnia domyślny zestaw błysków, domyślnie delegując dostosowywanie do systemu I18n config/locales/en.yml
.
Niektóre przykłady niestandardowych respondentów, których użyłem w poprzednich projektach, obejmują respondera, który automatycznie dekorował moje zasoby i zapewniał domyślny zestaw tytułów stron z interfejsem do łatwego dostosowywania lub zastępowania tytułu strony.
self.responder =
jak tylkoresponder =
przypiszesz do lokalnego