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?
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.
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
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.
Vous avez besoin des deuxlink_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'
jQuery est requis pour pouvoir exécuter la requête avec DELETE. Assurez-vous de ne pas le laisser tomber de votre application.js.
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
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
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>
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
É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 %>
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.
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.
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
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).
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 .
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
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.