web-dev-qa-db-fra.com

Devise: Pourquoi mon lien de déconnexion ne fonctionne-t-il pas?

le problème: en résumé, lorsque je tente d'installer un lien de déconnexion vers mon application, il ne fonctionne pas. Voici tout le contexte que je peux penser à mettre ici (si vous voulez autre chose, s'il vous plaît piquez-moi) ...

J'ai ceci dans une vue haml:

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

Cela génère ceci dans la vue:

<a href="/users/sign_out" data-method="delete" rel="nofollow">Logout</a>

J'ai vérifié que dans mon config/initializers/devise.rb j'ai ce paramètre non commenté et correct:

config.sign_out_via = :delete

J'ai validé l'itinéraire suivant:

destroy_user_session DELETE /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}

J'ai aussi cette astuce dans mes routes.rb, et je suppose que cela est lié à mon problème:

devise_for :users, :controllers => {:sessions => "devise/sessions", :registrations => "users"}
resources :users

Ce dernier bit est parce que je veux gérer (éditer, créer et supprimer) des utilisateurs dans mon propre contrôleur. 

Le message d'erreur que je reçois est le suivant: 

ActiveRecord::RecordNotFound in UsersController#show

Couldn't find User with ID=sign_out
Rails.root: /home/jaydel/projects/mbsquared-projects/Wilson-Goldrick

app/controllers/users_controller.rb:16:in `show'

Dans mes journaux de serveur, je vois ceci pour la demande:

Started GET "/users/sign_out" for 127.0.0.1 at 2011-08-04 13:08:51 -0500
  Processing by UsersController#show as HTML
  Parameters: {"id"=>"sign_out"}

Quelqu'un a des idées?

42
jaydel

Le problème réside dans le fait que, dans vos journaux, la demande de déconnexion est une demande GET.

Started GET "/users/sign_out"

Mais la voie de sortie est un DELETE

destroy_user_session DELETE /users/sign_out(.:format) 

La raison pour laquelle vous obtenez une exception est qu’elle est confondue avec l’un des itinéraires créés par resources :users qui ressemble à quelque chose comme:

edit_user GET /users/(:id)(.:format) {:action=>"edit", :controller=>"users"}

Fondamentalement, 'sign_out' est confondu avec un identifiant.

Je ne suis pas sûr de savoir pourquoi le lien de suppression ne passe pas par une requête DELETE. Bien que changeant

config.sign_out_via = :delete

être :get pourrait résoudre le problème.

16
Olives

Pour résoudre ce problème, REST-Wise, consiste à modifier vos liens de déconnexion pour utiliser la méthode DELETE. C'est une solution très facile, qui change ceci:

link_to "Log out", destroy_user_session_path

pour ça:

link_to "Log out", destroy_user_session_path, :method => :delete 
83
Jay Beale

J'ai eu le même problème avec Rails 3.2 lorsque j'ai supprimé de application.js cette ligne:

//= require jquery_ujs

Donc, je pense que vous devez insérer cette ligne dans votre application.js si vous ne l'avez pas là. 

PS. Ce comportement signifie que l’adaptateur Rails pour jquery ne fonctionne pas. Donc, vous devez vous assurer qu'il est chargé dans votre navigateur HTML. Vous devriez le tester en mode de développement car vous aurez compressé js en production et il sera très difficile d'y trouver quelque chose.

33
ka8725

Vous avez besoin des deux
link_to "Log out", destroy_user_session_path, method: :delete 

&& ceux-ci sont inclus dans application.js 

//= require jquery
//= require jquery_ujs

. Évidemment, n’oubliez pas d’ajouter ceci à Gemfile si, pour une raison quelconque, il n’est pas là. 

gem 'jquery-Rails'

6
webgen

jQuery est requis pour pouvoir exécuter la requête avec DELETE. Assurez-vous de ne pas le laisser tomber de votre application.js.

4
Christoph

C'est une vieille question, mais la réponse acceptée n'est pas la bonne façon de résoudre ce problème (bien que ce soit un bon diagnostic du problème).

Quand j’ai rencontré cela aujourd’hui, mon fichier de routes est apparu comme suit:

  root :to => 'welcome#index' 

  resources :users    
  devise_for :users

Comme mentionné par Olives, la déclaration de ressources est simplement la cause de problèmes. J'avais simplement besoin d'inverser l'ordre de mes routes ... 

 root :to => 'welcome#index' 

  devise_for :users
  resources :users
4
pws5068

J'ai vérifié toutes ces solutions, mais personne n'a travaillé pour moi. Enfin, j’ai trouvé que, dans l’en-tête, j’ai supprimé deux lignes, y compris les balises d’application et la méta de csrf.

Donc, si quelqu'un a ce problème avec aucune solution à ce stade - vérifiez si vous avez l'en-tête de la page (notation HAML) 

= javascript_include_tag 'application'
= csrf_meta_tags 
2
RafeekPro

C'est une vieille question, mais je voulais un moyen qui ne nécessite pas de JavaScript. Rails active "DELETE" comme des requêtes avec une entrée masquée qui définit method sur delete. Utilisez un vrai <form> et laissez Rails générer les entrées cachées nécessaires:

<%= form_for(resource, as: resource_name,
    url: destroy_user_session_path, html: { method: :delete }) do |f| %>
  <%= f.submit "Log out" %>
<% end %>

ce qui précède génère quelque chose comme:

<form accept-charset="UTF-8" action="/users/sign_out" method="post">
  <div style="display:none">
    <input name="utf8" type="hidden" value="✓">
    <input name="_method" type="hidden" value="delete">
    <input name="authenticity_token" type="hidden" value="1234">
  </div>
  <input name="commit" type="submit" value="Log out">
</form>
2
Ross Allen

Vous devez également vérifier si resources :users est sous devise_for :users et est la méthode du lien delete

link_to "Logout", destroy_user_session_path, method: :delete

si les deux ont raison, votre bouton de déconnexion devrait fonctionner 

1
user212131

Étant donné que le PO mentionnée et que ce problème m’était aussi arrivé, j’ai juste voulu y revenir. Rails fournit quelques aides pour résoudre ce problème sans jQuery.

Voici la réponse de Ross, mais en utilisant le modèle current_user de Devise:

<%= form_for(current_user,
    url: destroy_user_session_path, html: { method: :delete }) do |f| %>
    <%= f.submit "Log out" %>
<% end %>

Ou le plus succinct button_to helper qui crée un formulaire similaire:

<%= button_to "Log out", destroy_user_session_path, method: :delete %>
1
JorgePinon

Je devais aborder cette question différemment, comme mon application.rb:

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

et échouait toujours. Il s’avère que j’ai eu besoin de définir config.serve_static_assets = true dans/environment/development, test and production.rb. Ce lien était ce qui m'a aidé à comprendre.

1
ScottJShea

Si vous avez également plusieurs sources jQuery dans votre application Rails, vous devez utiliser celle par défaut spécifiée dans le fichier Gemfile.

assurez-vous d'avoir dans votre Gemfile

gem 'jquery-Rails'

et dans vos actifs, vous ne disposez d'aucun autre fichier source JQuery.

dans mon cas, j'avais un deuxième fichier JQuery autre que le fichier par défaut déclaré dans le fichier Gemfile, ce qui a provoqué des conflits.

si vous aviez précédemment ces sources, veillez à recompiler les éléments si vous les aviez précédemment.

1
Leonard Kakande

Je conviens qu'il est plus reposant d'utiliser la méthode http DELETE, j'aime créer un point de terminaison simple pour détruire une session utilisateur avec une méthode GET. 

en l'ajoutant à config/routes.rb

devise_scope :user do
  get '/logout',  :to => 'sessions#destroy'
end
0
errata

Si vous rencontrez ce problème en production et que vous utilisez le pipeline d'actifs, vous devez souvent:

rake assets:clobber afin de vider vos actifs publics. Puis rake assets:precompile avant de valider et de pousser votre code (sauf si votre Push précompile, alias Heroku).

0
EARnagram

la raison peut être dans le mauvais ordre connexion bootstrap-sprockets

le bon ordre:

// app/assets/javascripts/application.js

...

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require_tree .
0
askrynnikov

1) Je pense que vous aurez peut-être besoin d'installer ci-dessous gem, la requête avec la méthode:: delete fonctionnera sinon,

https://github.com/Rails/jquery-Rails

2) Ajoutez ces deux lignes ci-dessous dans application.js

//= require jquery
//= require jquery_ujs
0
Gurudath BN

Comme mentionné par Tombart ci-dessus, la réponse a été de remettre l'appel Rails-ujs dans mon fichier application.js. 

//= require Rails-ujs
//= require turbolinks

Je les avais initialement supprimés pour empêcher les erreurs de réévaluer mes scripts dans le pied de page. Ma solution consistait à créer un fichier de compilation footer.js avec les ressources que je voulais dans le pied de page.

//= require jquery-3.2.1.min
//= require jquery-ui-1.12.1.min
//= require materialize
//= require init

Puis dans mon fichier /initializers/assets.rb en ajoutant une précompile

Rails.application.config.assets.precompile += %w( footer.js )

Vous pouvez ensuite appeler les éléments suivants dans votre fichier layout/application.html.erb.

<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'footer' %>

Je garde la ligne d'application dans mon en-tête et ajoute mon nouvel appel "footer" avant la fin de ma balise body.

0
wsizoo