2014-06-06 12 views
10

Rails 4 ha introdotto le richieste PATCH come metodo di richiesta predefinito durante gli aggiornamenti parziali (comuni) sugli oggetti. Questo è conforme agli standard HTTP e una buona (più vecchio) posta a discutere questa decisione può essere trovato qui:È possibile disabilitare la rotta PUT standard in Rails 4?

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

Quando si definisce una risorsa in config/routes.rb come

resources :books 

quindi i seguenti itinerari sono creato per impostazione predefinita in rotaie 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 

Come sto sviluppando una nuova applicazione e non devo mi interessa la retrocompatibilità, vorrei rimuovere il percorso obsoleto PUT.

C'è un modo semplice per realizzare questo in config/routes.rb?


spiegazione perché questo percorso PUT mi dà fastidio: Sto usando il swagger-docs gem per la generazione automatica di documentazione per la mia spavalderia API. A causa del comportamento descritto, ho sempre due definizioni di endpoint per le richieste di aggiornamento (PUT e PATCH) per ogni risorsa. Inoltre, poiché si tratta di un percorso potenzialmente deprecating, vorrei che la mia API non la supportasse da oggi in poi.


UPDATE a causa delle prime risposte nella direzione sbagliata vorrei chiarire: io non voglio rimuovere l'azione 'update', ma solo il percorso PUT obsolete, mantenendo il percorso PATCH.

risposta

7

Per rispondere alla mia domanda: no, non è attualmente possibile disabilitare la generazione di default della combinazione PUT/PATCH in rotaie 4, che può essere visto chiaramente quando si cerca alla fonte di ActionDispatch :: Routing a https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/mapper.rb e soprattutto quelle linee:

 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 

Ovviamente, non v'è (attualmente) non condizionale per escludere il percorso PUT. Preparerò un problema o tirerò una richiesta per questo e tornerò più tardi con il risultato di ciò.

Fino ad allora, la soluzione migliore sarebbe quella che ha suggerito Jorge de los Santos, anche se ciò equivarrebbe a inquinare lo config/routes.rb.

5

Sì è, controllare la documentazione:

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

resources :photos, except: :update 

PATCH e PUT sono pensati per usi diversi. Finché l'aggiornamento è parziale, dovresti usare PATCH, ma se stai aggiornando tutto devi usare PUT. Questo può sembrare confuso, ma per esempio supponiamo che stiate aggiornando il modello associato, questa potrebbe essere considerata un'azione put al posto di una patch se non state modificando un'informazione parziale, state aggiornando l'intera relazione.

Anche PUT viene utilizzato per aggiornare o creare, soy potrebbe essere trovato utile quando si aggiungono risorse nidificate.

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

--------------- EDIT con la soluzione:

Per ignorare mette annuncio:

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

Rails cattura l'patch prima le risorse e disabiliterà put e patch per l'aggiornamento.

Riferimento:

Override "show" resource route in Rails

+0

Grazie per la risposta. Usando except:: update rimuoverà sia route PUT che PATCH, che non è quello che voglio. Per quanto riguarda la tua spiegazione delle differenze: è corretto, ma il post del blog che ho collegato nella domanda spiega in modo decente, che in pratica non eseguiamo mai richieste PUT reali nelle nostre API. Raramente sostituisci interi oggetti (ad esempio created_at) e anche update-or-create non ha senso in molte API perché l'ID viene solitamente creato dal database, non dal consumer API, quindi devi creare tramite POST –

+1

Capisco che ma tu hai per essere consapevole che: 1) Non tutti i server accettano patch come spiegato nel post del mio blog 2) In un'API l'azione di aggiornamento della richiesta non sa se l'entità aggiornata esiste, o si ha una sorta di: errore non trovato nell'entità . O ti ritroverai ad aggiornare qualcosa di inesistente. 3) Tutte le azioni PUT reindirizzeranno su una rotta inesistente. Modifica con un tipo di soluzione. – tebayoso

+1

Vedo il punto in cui non tutti i server accettano PATCH, ma non svolge alcun ruolo per la mia applicazione. Non capisco il tuo secondo punto, però. ovviamente un'azione di aggiornamento verificherà se l'elemento referenziato esiste e genera un errore altrimenti. Qual è la differenza tra il comportamento atteso di PUT e PATCH qui? Il tuo terzo punto è positivo, perché: voglio che la mia API ** non ** definisca la rotta PUT, in modo che i consumatori non la implementino. Questo è quello per cui sono qui.Inoltre, il link sopra spiega che hanno mantenuto la rotta PUT solo per la compatibilità all'indietro. –

0

Un paio di anni e una versione principale di Rails in seguito, non sembrano esserci progressi su questo problema.

Questo ha fatto il lavoro per me in cima routes.rb:

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

Poiché il metodo set_member_mappings_for_resource menzionata nella risposta del PO chiama put, questo rende semplicemente un no-op.

Se sono necessari i percorsi put, è possibile inserirli sopra questa riga. Se si desidera essere fantasiosi, è possibile definire un metodo without_verbs(*verbs, &block) che sostituisce temporaneamente i vari metodi di verbo, restituisce e quindi li reimposta.

0

un'altra soluzione per ignorare PATCH è il seguente:

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

Questo si tradurrà in una chiamata al metodo event sul SomeResourceController quando chiamiamo questo percorso PATCH /some_resources/:id

o per disattivarlo:

resources :some_resource, except: :update do 
    member { put action: :update } 
end 
Problemi correlati