Nessun percorso corrisponde a "/ users / sign_out" ideare rotaie 3


386

Ho installato devise sulla mia app e ho applicato quanto segue nel mio application.html.erbfile:

<div id="user_nav">
    <% if user_signed_in? %>
        Signed in as <%= current_user.email %>. This cannot be cheese?
        <%= link_to 'Sign out', destroy_user_session_path %>
    <% else %>
        <%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
    <% end %>
</div>

Ho corso rake routese confermato che tutti i percorsi sono validi.

Inoltre, nel mio routes.rbfile ho devise_for :userse root :to => "home#index".

Quando si fa clic sul collegamento "Esci", viene visualizzato il seguente errore di routing:

No route matches "/users/sign_out"

Qualche idea su cosa sta causando l'errore?


1
Hai riavviato l'app dopo aver aggiunto i percorsi? Le modifiche al percorso diventano effettive solo all'avvio.
Thilo-Alexander Ginkel,

2
Sì. L'ho fatto di nuovo per essere al sicuro. Inoltre, ho letto da qualche altra parte su Stack che potrebbe essere un problema con la nuova gemma ideata non compatibile con Rails 3.0.3, quindi ho provato a cambiare la mia gemma ideata da 1.4.2 a gem 'devise', :git => 'git://github.com/plataformatec/devise.git'. Ciò non ha fatto nulla però.
vich

Cambiare la voce nel Gemfile non ti darebbe una versione sempre più nuova di Devise? Hai provato a specificare un numero di versione inferiore?
Leo Cassarani,

Potresti pubblicare il tuo file trails.rb
felix il

1
La seconda risposta di Jessie di seguito ha funzionato perfettamente.
Vich

Risposte:


568

Penso che il percorso per uscire sia un DELETEmetodo. Ciò significa che il link di disconnessione deve essere simile al seguente:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

Il tuo non include la :method => :deleteparte. Inoltre, tieni presente che per farlo funzionare devi anche includere <%= javascript_include_tag :defaults %>nel tuo file di layout ( application.html.erb).


3
Posso tranquillamente dire che non ho mai dovuto farlo in nessuna delle mie app Rails. link_to "Sign out", destroy_user_session_pathè sempre stato abbastanza buono per me.
Leo Cassarani,

8
Ho fatto il test e funziona per me. Non dimenticare che le cose cambiano da una versione all'altra (sia in Rails o Devise). Inoltre, il logout è un comportamento che cambia stato che non dovrebbe essere fatto usando i metodi GET (a mio modesto parere).
Jessie Dedecker,

23
Per ulteriori informazioni, la ragione per cui questo è stato modificato nell'ultima versione di Devise è descritta qui e qui .
Jessie Dedecker,

6
Ho riscontrato questo stesso problema e il suggerimento di Jessie ha funzionato per me. Mi aspetto che chiunque stia attraversando il railscast escogitato alla fine finirà qui a causa di questo cambiamento ...
johnnygoodman,

2
puoi anche digitare questo nella tua console web per provarlo $("<a href='/users/sign_out' data-method='delete'>Sign out</a>").appendTo('body');- se jQuery è caricato sulla pagina.
mraaroncruz,

133

Ho cambiato questa riga in devise.rb:

config.sign_out_via = :delete

per

config.sign_out_via = :get

e ha iniziato a funzionare per me.


22
Il modo in cui era stato fatto in precedenza era di disconnettersi utilizzando "GET / users / sign_out", ma l'hanno cambiato in "ELIMINA" per renderlo più RESTful. L'autore ha spiegato che un GET non dovrebbe apportare modifiche al server come la disconnessione.
Jonathan Allard,

2
questo ha funzionato per me. Mentre apprezzo che non sia una buona pratica, le altre risposte falliscono. Non vedo perché !!
Lieve Fuzz

8
È anche possibile utilizzare un array se si desidera supportare più metodi. Ad esempio: config.sign_out_via = [ :post, :delete ]oppure devise_for :users, :sign_out_via => [ :post, :delete ], come descritto in devise / rails / route.rb .
Hosam Aly,

2
Non userei una richiesta GET per disconnettersi poiché apre l'utente a un attacco XSRF. (Hacker crea un sito Web con un tag immagine con src = " foo.com/users/sign_out ", l'utente lo visita e si disconnette).
Ryan Doherty,

1
@RyanDoherty Id Non mi sbaglio, XSRF è ancora possibile (l'attaccante deve solo utilizzare un modulo con action = "DELETE" sull'URL di destinazione, quindi inviarlo automaticamente al caricamento della pagina).
Maël Nison l'

60

Probabilmente non hai incluso il file javascript jquery_ujs. Assicurati di utilizzare l'ultima versione di jquery-ujs: https://github.com/rails/jquery-ujs e gli ultimi file disponibili:

rails generate jquery:install

Si dovrebbe non avere più file di rails.js. Se lo fai, probabilmente non sei aggiornato. Assicurati che anche questo file sia caricato con i valori predefiniti, in config / application.rb

config.action_view.javascript_expansions[:defaults] = %w(jquery.min jquery_ujs)

(Anche in questo caso, si dovrebbe non avere file di rails.js qui). Infine, aggiungi il link come documentato su Devise wiki (stile haml):

= link_to('Logout', destroy_user_session_path, :method => 'delete')

E tutto andrà bene.


8
Ho avuto: method => 'delete' nel mio link_to, il problema era jquery_ujs non incluso, questa soluzione ha risolto il mio problema. Ricorda di mettere le "rotaie" della gemma nel tuo file di gemme.
Rob Bazinet,

2
Grazie ha funzionato per me. Invece di usare i valori predefiniti puoi anche usarejavascript_include_tag "jquery_ujs"
Bnicholas,

Buona cattura, grazie! Sto usando request.js per caricare i file in modo asincrono e ho dimenticato di richiedere jquery_ujs.
Dan Fairaizl,

Ho assunto che "u" significava non compresso e rimosso questa riga da application.js. Presupposto negativo, suppongo. Grazie.
Jeff,

Questo problema è stato risolto (nella mia app 100th devise based) dopo aver cambiato twitter bootstrap da less a sass e ho dimenticato di aggiungere // = request jquery_ujs nel mio application.js.
Joe,

31

La possibilità di rendere il collegamento alla disconnessione una chiamata DELETE RESTful richiede un attributo html data-method = "delete"utilizzando il codice rails = link_to('Logout', destroy_user_session_path, :method => :delete).

Tuttavia, se non hai jquery-ujsinstallato la gemma o non stai chiamando il javascript risultante nella tua application.html tramite = javascript_include_tag "application", la risposta verrà inviata come richiesta GET e il percorso fallirà.

Hai alcune opzioni se non vuoi usare jquery-ujso non riesci a trovare un modo per farlo funzionare:

  1. Cambia config.sign_out_viain uguale :geta devise.rb(non raccomandato, poiché DELETE è la query RESTful appropriata)
  2. OPPURE Cambia link_toin = button_to('Logout', destroy_user_session_path, :method => :delete). Con button_toRails farà il lavoro pesante nel fare la corretta ELIMINA chiamata. È quindi possibile assegnare uno stile al pulsante per assomigliare ad un collegamento, se lo si desidera.

Il passaggio da link_to a button_to ha funzionato per me, ma davvero non capisco perché? Cosa è cambiato esattamente a parte l'html / css?
Spyros Mandekis,

1
Ha a che fare con la "magia" delle rotaie che genera automaticamente html da funzioni come button_to e link_to. Accade solo che la magia delle rotaie per button_to specifichi la corretta chiamata DELETE RESTful e link_to no. Se dovessi indovinare, direi che il motivo è che gli elementi del pulsante html possono gestire una chiamata DELETE (o raggruppare con un campo nascosto che specifica l'azione) mentre i collegamenti regolari non possono.
Will Nathan,

Grazie per questo. Ho configurato la mia app per gestire manualmente jquery, quindi non avevo jquery-ujs. L'installazione con bower o bundler e l'inclusione della riga appropriata per la pipeline delle risorse risolve il problema.
jrhorn424,

1
Questa mi sembra la soluzione più sicura e portatile.

Informazioni su button_to, Rails genera un formper l'intera azione. Ecco perché è possibile utilizzare il :deletemetodo con button_toe non con link_to, basta vedere l'HTML generato.
Fernando Fabreti,

25

Prova ad aggiungere un nuovo percorso per ideare / sessioni # distruggere e collegarti a quello. Per esempio:

routes.rb
devise_for :users do
  get 'logout' => 'devise/sessions#destroy'
end

Visualizza:

<%= link_to "Logout", logout_path %>

Ottenere lo stesso errore di mmichael. Questo test sopra funziona per me.
RTFMINC

1
Ho anche avuto lo stesso errore di mmichael. La soluzione sopra funzionerà ma non è come dovrebbe essere riparata. Le route predefinite in Devise includono già la route di disconnessione come metodo DELETE. Normalmente non è necessario modificare autonomamente le route predefinite. Ecco perché puoi risolverlo semplicemente aggiungendo un parametro separato alla link_tochiamata, come descritto nell'altra risposta.
Jessie Dedecker,

Non è necessario aggiungere una route al route.rb fiile, devise consente di modificare il metodo in devise.rb che si trova nella directory / confit / initializer /.
Travis Pessetto,

6
Mai e poi mai avere il percorso di logout come GET.
Jagira,

@Jagira perché? Perché non sia DELETE che GET?
hrdwdmrbl,

14

Usalo nel tuo file route.rb:

devise_for :users do
    get '/users/sign_out' => 'devise/sessions#destroy'
end

13

Ho avuto lo stesso problema con le rotaie 3.1.0 e ho risolto aggiungendo nel file le seguenti righe:

app/assets/javascripts/application.js
//= require_tree
//= require jquery
//= require jquery_ujs

Se si utilizza bower, provare // = request jquery-ujs.
monteirobrena,

10

Con un'eccezione, la risposta di Jessie ha funzionato per me:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

modificare:

:delete

... per:

'delete'

Quindi il codice che ha funzionato per me è:

<%= link_to "Sign out", destroy_user_session_path, :method => 'delete' %>

Grazie per aver pubblicato questo frammento di codice, sign_out ora funziona per me.
Buk

9

Molte risposte alla domanda già. Per me il problema era duplice:

  1. quando espando i miei percorsi:

    devise_for :users do 
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
  2. Stavo avvertendo che questo è ammortizzato, quindi l'ho sostituito con:

    devise_scope :users do
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
  3. Ho pensato di rimuovere il mio jQuery. Scelta sbagliata. Devise utilizza jQuery per "fingere" la richiesta DELETE e la invia come GET. Pertanto è necessario:

    //= require jquery
    //= require jquery_ujs
  4. e ovviamente lo stesso link di molti menzionati prima:

    <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

puoi spiegare il terzo punto ... ne sono stato vittima e voglio capirlo di più
Rahul Dess,

1
Certamente. Il tuo sito web non sta davvero inviando richieste DELETE. Francamente utilizzerà solo GET e POST. Perché nella comunità di Rails è stato concordato che (per buoni motivi) vogliamo eliminare i record quando inviamo la richiesta DELETE, dobbiamo usare un piccolo trucco. Quando nel tuo ERB specifichi il metodo:: delete rails lo convertirà in tag HTML5: data-method = "delete" e lo invierà come GET. Ora è qui che entrano in gioco jQuery-ujs e jQuery. Consentono all'app di riconoscere che è quello che stai facendo. In modo che la tua richiesta possa essere abbinata all'azione del controller.
Lukasz Muzyka,

senza quelle gemme, questo non funzionerà. Naturalmente, è possibile modificare le impostazioni di escavatore (in escavatore inizializzatore) e chiedergli di usare GET anziché DELETE.
Lukasz Muzyka,

7

Inserisci:

  <%= csrf_meta_tag %>  and 
  <%= javascript_include_tag :defaults %>  to layouts

Usa questi tag link_to

 link_to 'Sign out', destroy_user_session_path, :method => :delete

  or

 link_to 'Sign out', '/users/sign_out', :method => :delete

Nei percorsi aggiungi:

  devise_for :users do
    get '/users/sign_out' => 'devise/sessions#destroy'
  end

7

Un'altra opzione è quella di configurare il logout per essere un GET anziché un DELETE, puoi farlo aggiungendo la seguente riga /config/initializers/devise.rb

config.sign_out_via = :get

Ma come ha scritto Steve Klabnik sul suo blog (http://blog.steveklabnik.com/2011/12/11/devise-actioncontroller-routingerror-no-route-matches-get-slash-users-slash-sign-out.html ) prova a utilizzare DELETE a causa della semantica di questo metodo.


Solo questa risposta ha funzionato per me per Devise 3.5.1 e Rails 4.2.3
sagar junnarkar

Non dimenticare di riavviare il server :)
jackmin

6

Se stai usando Rails 3.1 assicurati che il tuo application.html.erb esca sia simile a:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

E che il tuo javascript includa la linea è simile al seguente

<%= javascript_include_tag 'application' %>

La mia ipotesi è che alcune gemme sovrascrivano la nuova struttura della posizione default.js.


Grazie! Questo mi stava facendo impazzire!
Dorian,

5

Dai un'occhiata con il codice sorgente in github:

https://github.com/plataformatec/devise/commit/adb127bb3e3b334cba903db2c21710e8c41c2b40#lib/generators/templates/devise.rb (data: 27 giugno 2011)

  • # Il metodo HTTP predefinito utilizzato per disconnettere una risorsa. L'impostazione predefinita è: get. 188
  • # config.sign_out_via =: ottieni 187
  • # Il metodo HTTP predefinito utilizzato per disconnettere una risorsa. L'impostazione predefinita è: elimina. 188
  • config.sign_out_via =: elimina

5

Bene, ragazzi per me è stato solo rimuovere il: method =>: delete

<%= link_to('Sign out', destroy_user_session_path) %>

5

Questo significa che non hai generato i file jquery dopo aver installato la gemma jquery-rails. Quindi prima devi generarlo.

rails generate devise:install

Prima opzione:

Questo significa che devi cambiare la seguente riga /config/initializers/devise.rb

config.sign_out_via =: elimina in config.sign_out_via =: get

Seconda opzione:

Si cambia solo questa riga <%= link_to "Sign out", destroy_user_session_path %>per <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>il file di visualizzazione.

Di solito :method => :deletenon è scritto per impostazione predefinita.


5

Voglio aggiungere a questo anche se è un po 'vecchio.

il link "sign_out" non funzionava, nonostante avesse: method =>: delete.

Il commento che indica che <%= javascript_include_tag :defaults %>deve essere incluso mi ha ricordato che avevo recentemente aggiunto lo script java JQuery e ho usato semplici <script src=""/>tag per includerli.

Quando li ho spostati da dopo: default a prima, sign_out ha ripreso a funzionare.

Spero che questo aiuti qualcuno.


5

La maggior parte delle risposte sono parziali. Ho riscontrato questo problema molte volte. Due cose devono essere affrontate:

<%= link_to(t('logout'), destroy_user_session_path, :method => :delete) %>

il metodo di eliminazione deve essere specificato

Quindi escogitare utilizza jquery, quindi è necessario caricarli

   <%= javascript_include_tag "myDirectiveJSfile" %> 

e assicurati che ENTRAMBI jquery e jquery-ujs siano specificati in myDirectiveJSfile.js

//= require jquery
//= require jquery_ujs

5

Non dimenticare di includere la seguente riga in application.js (Rails 3)

//= require_self
//= require jquery
//= require jquery_ujs

Includi jquery_ujsnella mia applicazione rotaie e funziona ora.


4

Se stai utilizzando HTTPS con idea , si interromperà se il tuo collegamento di disconnessione è alla versione non sicura. Sul back-end, reindirizza alla versione protetta. Quel reindirizzamento è un GET, che causa il problema.

Assicurati che il tuo collegamento utilizzi HTTPS. Puoi forzarlo con il protocol: "https"tuo aiutante url (assicurati di usare l'helper url e non l'aiutante del percorso).

<%= link_to "Sign out", destroy_user_session_url(protocol: "https"), method: :delete %>

4
  devise_for :users
  devise_scope :user do
    get '/users/sign_out' => 'devise/sessions#destroy'
  end

3

Il problema inizia con le rotaie 3.1 ... /app/assets/javascript/basta cercare application.js.

Se il file non esiste, crea un file con quel nome non so perché il mio file scompaia o non sia mai stato creato "rails new app"....

Quel file è l'istanza di jquery....


3

Molte soluzioni ci sono. ma soprattutto usa questo,

<%= link_to 'Sign out', destroy_user_session_path, method: :delete %>

o config devise.rb con il metodo sign_out corretto

In devise.rb

config.sign_out_via = :delete ( or  :get which u like to use.) 

3

uso :gete :deletemetodo per il tuo percorso:

devise_scope :user do
  match '/users/sign_out' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:get, :delete]
end

Nota: deve esserci devise_for: utenti dichiarati separatamente da questo. vedere la risposta da dipole_moment.
Taylored Web Sites

2

Nel tuo route.rb:

 devise_for :users do
    get '/sign_out' => 'devise/sessions#destroy'
    get '/log_in' => 'devise/sessions#new'
    get '/log_out' => 'devise/sessions#destroy'
    get '/sign_up' => 'devise/registrations#new'
    get '/edit_profile' => 'devise/registrations#edit'
 end

e nel tuo application.html.erb:

<%if user_signed_in?%>
          <li><%= link_to "Sign_out", sign_out_path %></li>
<% end %>

1
La sintassi è ora: devise_for: gli utenti quindi i get devono essere inseriti in devise_scope: l'utente fa NOTA: singolare: utente per devise_scope
Web Sites

2

Questo è quello che ho fatto (con Rails 3.0 e Devise 1.4.2):

  1. Assicurati che la tua pagina carichi rails.js
  2. Usa questo parametro: 'data-method' => 'delete'
  3. Buona idea per aggiungere questo parametro:: rel => 'nofollow'

1

Verifica se il tuo route.rb ha una "risorsa: utenti" prima di un "devise_for: users" quindi prova a scambiarli:

  1. Lavori

    • devise_for: utenti
    • risorse: utenti
  2. Non riesce

    • risorse: utenti
    • devise_for: utenti

1

la ':method => :delete'in page è' data-method="delete"'quindi la tua pagina deve avere jquery_ujs.js, inoltrerà il link con il metodo delete non method get


1

So che questa è una vecchia domanda basata su Rails 3 ma mi sono appena imbattuto e risolto su Rails 4.0.4. Quindi ho pensato di risolvere il problema per chiunque avesse riscontrato questo problema con questa versione. Il tuo chilometraggio può variare ma ecco cosa ha funzionato per me.

Per prima cosa assicurati di aver installato le gemme ed esegui l'installazione del bundle.

gem 'jquery-rails'

gem 'turbolinks'

gem 'jquery-turbolinks'

In application.js controlla che tutto sia richiesto come di seguito.

Fai attenzione se questo gotcha : è //= require jquery.turbolinkse non//= require jquery-turbolinks

//= require jquery
//= require jquery_ujs
//= require jquery.turbolinks
//= require turbolinks
//= require_tree .

Successivamente, aggiungi i collegamenti appropriati nell'intestazione di application.html.erb.

<%= javascript_include_tag  "application", "data-turbolinks-track" => true %>
<%= javascript_include_tag :defaults %>

Sembra che ci siano molte varianti su come implementare il metodo di eliminazione che presumo dipende dalla versione di Rails che stai utilizzando. Questa è la deletesintassi che ho usato.

<p><%= link_to "Sign Out", destroy_user_session_path, :method => 'delete' %></p>

Spero che aiuti a scavare qualcuno da questo buco molto frustrante!


0

In generale, quando ricevi "Nessuna corrispondenza percorso" ma pensi di avere quel percorso definito, allora ricontrolla il verbo http / metodo di richiesta (sia esso get, put, post, cancella ecc.) Per quel percorso .

Se esegui percorsi di rake, vedrai il metodo previsto e puoi confrontarlo con il registro delle richieste.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.