Rails respond_with - dlaczego POST zwraca adres URL zamiast danych?
To jest pytanie „dlaczego to działa w ten sposób”, a nie „jak to zrobić”.
Moja aplikacja dzwoni do zewnętrznego API REST, który zwraca JSON i zwraca wynik jako część mojegoposiadać JSON API.
Używałem Rails 3respond_to
irespond_with
metody; w przypadkuGET
żądania, to działa tak, jak się tego spodziewam, po prostu przechodząc przez JSON.
W przypadkuPOST
, robi więcej, włączając w to przywrócenie adresu URL obiektu do przekazania:location
opcja. Ale ponieważ moim obiektem jest tylko JSON (nie ActiveRecord), pojawia się błąd.
Na przykład...
# POST /api/products.json with params id=:id
def create
query_string = "#{user_id}&id=#{params[:id]}"
@products = third_party_api_wrapper.products(query_string, 'POST')
respond_with @products
end
Moje opakowanie dla interfejsu API innej firmy tworzy żądanie POST, które wraca dobrze, a następnie Railsy zwracają błąd 500, który jest zapisywany w następujący sposób:
NoMethodError (undefined method `{"response":{"message":"product 4e1712d9ec0f257c510013f8 selected"}}_url' for #<MyController>
Railsy chcą, aby mój obiekt @products wiedział, jak utworzyć adres URL lokalizacji.
WYJAŚNIENIE: The@products
obiekt zwrócony przez interfejs API innej firmy jest czystym JSON - łańcuchem, który można zobaczyć osadzony w komunikacie dziennika błędów powyżej. Ten błąd występuje, ponieważ Railsy wydają się chcieć, aby obiekt był czymś więcej - w wewnętrznej obsłudze API Railsów jest to obiekt ActiveRecord.
Jeśli zastąpię nowyrespond_with
z sytaxem w starym stylu
respond_to do |format|
format.json { render :json => @products } # note, no :location or :status options
end
wtedy wszystko działa. I to właśnie zrobiłem, więc nie mam problemu „jak”, zamiast tego mam pytanie „dlaczego”.
Post Ryana Daigle na wstępie wyjaśnia, że oczekuje się tego, co się dzieje.
Moje pytanie brzmi:czemu robirespond_with
oczekiwać czegoś innego niż dane (i status HTTP?) i najwyraźniej tylko dlaPOST
.
Nie mówię, że to źle, po prostupróbować zrozumieć uzasadnienie implementacji Railsów.