2014-06-06 16 views
10

Rails 4 wprowadził żądania PATCH, aby być domyślną metodą żądania podczas wykonywania (wspólnej) częściowej aktualizacji obiektów. To konformalna standardów HTTP i dobre (starszych) po omówieniu tej decyzji można znaleźć tutaj:Czy można wyłączyć standardową trasę PUT w Railsach 4?

http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/

Podczas definiowania zasobów w config/routes.rb jak

resources :books 

następnie następujące trasy są utworzono domyślnie w szynach 4:

GET  /books  books#index 
    GET  /books/:id books#show 
    POST /books  books#create 
    DELETE /books/:id books#destroy 
    PATCH /books/:id books#update 
    PUT  /books/:id books#update 

Ponieważ opracowuję nową aplikację i nie muszę dbając o kompatybilność wsteczną, chciałbym usunąć przestarzałą trasę PUT.

Czy istnieje prosty sposób osiągnięcia tego w config/routes.rb?


Wyjaśnienie, dlaczego ta PUT trasa denerwuje mnie: Używam swagger-docs gem do automatycznego generowania dokumentacji Swagger dla mojego API. Z powodu opisanego zachowania zawsze mam dwie definicje punktów końcowych dla żądań aktualizacji (PUT i PATCH) dla każdego zasobu. Dodatkowo, ponieważ jest to potencjalnie przestarzała trasa, chciałbym, aby moje API nie obsługiwało tego od dzisiaj.


UPDATE z powodu pierwszych odpowiedziach zmierza w złym kierunku, chciałbym wyjaśnić: Nie chcę, aby usunąć „aktualizacji” działania, ale tylko przestarzałe trasa PUT zachowując trasę Patch.

Odpowiedz

7

Aby odpowiedzieć na moje własne pytanie: nie, w tej chwili nie jest możliwe, aby wyłączyć generowanie domyślnej kombinacji PUT/plaster na szynach 4, który można wyraźnie zauważyć, patrząc u źródła ActionDispatch :: trasy w https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb a zwłaszcza tych linii:

 def set_member_mappings_for_resource 
     member do 
      get :edit if parent_resource.actions.include?(:edit) 
      get :show if parent_resource.actions.include?(:show) 
      if parent_resource.actions.include?(:update) 
      patch :update 
      put :update 
      end 
      delete :destroy if parent_resource.actions.include?(:destroy) 
     end 
     end 

Oczywiście, nie jest (obecnie) nie warunkowe wyłączenia trasę PUT. Przygotuję sprawę lub wezwę na to zadanie i wrócę później z wynikiem tego.

Do tego czasu najlepszym rozwiązaniem byłoby to, co zasugerował Jorge de los Santos, chociaż w dużym stopniu zanieczyściłoby to config/routes.rb.

5

Tak to jest, sprawdzić dokumenty:

http://guides.rubyonrails.org/routing.html#restricting-the-routes-created

resources :photos, except: :update 

łata i PUT są przeznaczone do różnych zastosowań. Dopóki aktualizacja jest częściowa, powinieneś używać PATCH, ale jeśli aktualizujesz wszystko, musisz użyć PUT. Może to zabrzmieć myląco, ale na przykład załóżmy, że aktualizujesz powiązany model, może to być traktowane jako działanie wprowadzane zamiast poprawki, o ile nie modyfikujesz częściowych informacji, aktualizujesz całą relację.

Również PUT służy do aktualizacji lub tworzenia, soja może być przydatna podczas dodawania zagnieżdżonych zasobów.

http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/

--------------- EDIT roztworem:

przesłonić umieszcza reklamy:

PATCH 'route', to: 'books#update' 
resources :books, except: :update 

Szyny złapie łatkę przed zasoby i wyłączy instalację i poprawkę do aktualizacji.

referencyjny:

Override "show" resource route in Rails

+0

Dzięki za odpowiedź. Użycie except:: update usunie obie trasy PUT i PATCH, co nie jest tym, czego chcę. Jeśli chodzi o twoje wyjaśnienie różnic: to prawda, ale wpis na blogu, który podłączyłem w pytaniu wyjaśnia w przyzwoity sposób, że zasadniczo nigdy nie wykonujemy prawdziwych żądań PUT w naszych API. Rzadko zamieniasz całe obiekty (np. Created_at), a także update-or-create nie ma sensu w wielu interfejsach API, ponieważ identyfikator jest zwykle tworzony przez bazę danych, a nie przez klienta API, więc musisz utworzyć przez POST –

+1

Rozumiem to, ale masz być świadomym, że: 1) Nie wszystkie serwery akceptują poprawki, jak wyjaśniono w moim poście na blogu 2) W interfejsie API akcja aktualizacji żądania nie wie, czy zaktualizowany obiekt istnieje, czy istnieje jakiś rodzaj: nie znaleziono błędu jednostki . Albo okaże się, że odnawiasz coś nieistniejącego. 3) Wszystkie akcje PUT przekierują do nieistniejącej trasy. Edytowanie za pomocą rodzaju rozwiązania. – tebayoso

+1

Widzę punkt, w którym nie wszystkie serwery akceptują PATCH, ale nie odgrywają roli dla mojej aplikacji. Nie rozumiem jednak twojego drugiego punktu. oczywiście akcja aktualizacji sprawdzi, czy istnieje element, do którego istnieje odwołanie, i w przeciwnym razie wygeneruje błąd. Jaka jest różnica między oczekiwanym zachowaniem PUT i PATCH tutaj? Twój trzeci punkt jest dobry, ponieważ: Chcę, aby mój interfejs API ** nie ** definiował trasę PUT, tak aby konsumenci nie implementowali go. Po to tu jestem.Również powyższy link wyjaśnia, że ​​utrzymywały one tylko trasę PUT dla kompatybilności wstecznej. –

0

Kilka lat później i poważna wersja Railsa, nie wydaje się, aby nastąpił jakiś postęp w tej kwestii.

To nie praca dla mnie u góry routes.rb:

Rails.application.routes.draw do 
    def put(*) end 
    ... 

Ponieważ metoda set_member_mappings_for_resource wspomniano w odpowiedzi na PO apeluje put, to po prostu sprawia, że ​​no-op.

Jeśli potrzebujesz tras put, możesz umieścić je powyżej tej linii. Jeśli chcesz mieć ochotę, możesz zdefiniować metodę, która tymczasowo zastępuje różne metody czasownika, plony, a następnie je odkłada.

0

inne rozwiązanie, aby zastąpić Patch jest następujący:

resources :some_resources do 
    member { patch action: :event } 
end 

Spowoduje to wywołanie metody event na SomeResourceController gdy wzywamy tej trasie PATCH /some_resources/:id

lub ją wyłączyć:

resources :some_resource, except: :update do 
    member { put action: :update } 
end 
Powiązane problemy