「/ users / sign_out」に一致するルートはありませんdevise rails 3


386

私は自分のアプリにdeviseをインストールし、application.html.erbファイルに以下を適用しました:

<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>

私は走りrake routes、すべてのルートが有効であることを確認しました。

また、私のroutes.rbファイルにはとがdevise_for :usersありroot :to => "home#index"ます。

[ログアウト]リンクをクリックすると、次のルーティングエラーが発生します。

No route matches "/users/sign_out"

エラーの原因は何ですか?


1
ルートを追加した後、アプリを再起動しましたか?ルートの変更は起動時にのみ有効になります。
Thilo-Alexander Ginkel

2
はい。安全のためにもう一度やりました。また、Stackの他の場所で読んだところ、最新のdevise gemがRails 3.0.3と互換性がないことが問題である可能性があるため、devise gemを1.4.2からに変更してみましたgem 'devise', :git => 'git://github.com/plataformatec/devise.git'。それでも何もしませんでした。
11

Gemfileのエントリを変更しても、Deviseの最新バージョンが手に入るだけではありませんか?低いバージョン番号を指定してみましたか?
Leo Cassarani、2011

あなたのroutes.rbをファイル投稿できる
フェリックス

1
以下のジェシーによる2番目の答えは完璧に機能しました。
2011

回答:


568

サインアウトするDELETE方法は方法だと思います。つまり、サインアウトリンクは次のようにする必要があります。

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

あなたの:method => :deleteパーツは含まれていません。また、これが機能するために<%= javascript_include_tag :defaults %>は、レイアウトファイル(application.html.erb)にも含める必要があることに注意してください。


3
Railsアプリでこれを行う必要がなかったことは間違いありません。link_to "Sign out", destroy_user_session_path私にとってはいつも十分でした。
Leo Cassarani、2011

8
私はテストを行い、それは私のために機能します。あるバージョンから別のバージョンに変更されることを忘れないでください(それがRailsでもDeviseでも)。その上、ログアウトは状態を変更する動作であり、GETメソッドを使用して行うべきではありません(私の考えでは)。
Jessie Dedecker、2011

23
詳細については、これがDeviseの最新バージョンで変更された理由をここここで説明します
Jessie Dedecker、2011

6
私はこれと同じ問題に遭遇し、ジェシーの提案は私のために働いた。この変更により、デバイスのレールキャストを実行しているすべての人が最終的にここに到着することを期待しています...
johnnygoodman

2
これをWebコンソールに入力してテストすることもできます($("<a href='/users/sign_out' data-method='delete'>Sign out</a>").appendTo('body');jQueryがページにロードされている場合)。
mraaroncruz

133

私はdevise.rbでこの行を変更しました:

config.sign_out_via = :delete

config.sign_out_via = :get

そしてそれは私のために働き始めました。


22
以前は「GET / users / sign_out」を使用してサインアウトする方法でしたが、RESTfulにするために「DELETE」に変更しました。著者は、GETはログアウトなどのサーバーに変更を加えるべきではないと説明しました。
ジョナサンアラード2011

2
これは私のために働いた。それがベストプラクティスではないことを感謝していますが、他の回答は失敗しました。理由がわかりません!!
マイルドファズ

8
複数のメソッドをサポートする場合は、配列を使用することもできます。例:config.sign_out_via = [ :post, :delete ]またはdevise / rails / routes.rbでdevise_for :users, :sign_out_via => [ :post, :delete ]説明されているように
Hosam Aly、2012年

2
ユーザーをXSRF攻撃にさらすため、サインアウトにGETリクエストを使用しません。(ハッカーがsrc = " foo.com/users/sign_out "のイメージタグでWebサイトを作成し、ユーザーがアクセスしてログアウトします)。
Ryan Doherty、

1
@RyanDoherty Id間違いではありませんが、XSRFは引き続き可能です(攻撃者は、ターゲットURLでaction = "DELETE"のフォームを使用し、ページの読み込み時にそれを自動送信するだけです)。
–MaëlNison 2013

60

おそらくjquery_ujs JavaScriptファイルが含まれていません。jquery-ujsの最新バージョンを使用していることを確認してください:https : //github.com/rails/jquery-ujsおよび使用可能な最後のファイル:

rails generate jquery:install

これ以上rails.jsファイルは必要ありません。もしそうなら、あなたはおそらく時代遅れです。また、このファイルがconfig / application.rbにデフォルトでロードされていることを確認してください

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

(ここでも、rails.jsファイルをここに置くべきでありませ)。最後に、Devise wiki(hamlスタイル)に記載されているリンクを追加します

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

そして、すべてがうまくいきます。


8
link_toに:method => 'delete'がありました。問題はjquery_ujsが含まれていないことでした。この解決策で問題が解決しました。あなたのgemfileにgem 'jquery-rails'を置くことを忘れないでください。
Rob Bazinet 2011

2
これは私のために働いてくれてありがとう。デフォルトを使用する代わりに使用することもできますjavascript_include_tag "jquery_ujs"
Bnicholas

良いキャッチ、ありがとう!require.jsを使用してファイルを非同期に読み込み、jquery_ujsを要求するのを忘れていました。
Dan Fairaizl 2013年

「u」は圧縮されていないことを意味すると想定し、この行をから削除しましたapplication.js。悪い仮定だと思います。ありがとう。
ジェフ

この問題は、twitterブートストラップをlessからsassに変更した後(私の100番目のデバイスベースのアプリで)発生し、// = require jquery_ujsをapplication.jsに追加し忘れていました。
Joe

31

ログアウトリンクをDELETE RESTful呼び出しにする機能にはdata-method = "delete"、railsコードを使用してhtml属性が必要です= link_to('Logout', destroy_user_session_path, :method => :delete)

ただし、gemをjquery-ujsインストールしていない場合、またはapplication.htmlで結果のjavascriptを呼び出していない場合= javascript_include_tag "application"場合、応答はGETリクエストとして送信され、ルートは失敗します。

使用したくない場合、jquery-ujsまたは機能させる方法が見つからない場合は、いくつかのオプションがあります。

  1. 内でconfig.sign_out_via等しいに変更:getdevise.rb(DELETEが適切なRESTfulクエリであるため、推奨されません)
  2. またはをに変更link_to= button_to('Logout', destroy_user_session_path, :method => :delete)ます。button_toRailsの適切なDELETE呼び出しを行う上で力仕事を行います。必要に応じて、ボタンのスタイルをリンクのようにすることができます。

link_toからbutton_toへの変更は私にとってはうまくいきましたが、なぜ私は本当に理解していませんか?html / cssとは何が違うのですか?
Spyros Mandekis 2012年

1
これは、button_toやlink_toなどの関数からHTMLを自動生成するRailsの「マジック」に関係しています。たまたま、button_toのrails magicは適切なRESTful DELETE呼び出しを指定し、link_toは指定しません。推測しなければならないのは、通常のリンクではできませんが、HTMLボタン要素がDELETE呼び出し(またはアクションを指定する非表示フィールドとのバンドル)を処理できるためです。
Nathanは

これをありがとう。手動でjqueryを処理するようにアプリを設定したので、jquery-ujsはありませんでした。bowerまたはbundlerを使用してインストールし、アセットパイプラインに適切な行を含めると、問題が解決します。
jrhorn424 2013

1
これは、私にとって最も安全でポータブルなソリューションのようです。

についてbutton_to、Railsはformアクション全体に対してを生成します。そのため、:deleteメソッドをbutton_toで使用して使用することはできませんlink_to。生成されたHTMLを確認してください。
フェルナンドファブレティ

25

devise / sessions#destroyに新しいルートを追加して、それにリンクしてみてください。例えば:

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

見る:

<%= link_to "Logout", logout_path %>

mmichaelと同じエラーが発生します。この上記のテストは私にとってはうまくいきます。
rtfminc

1
私もmmichaelと同じエラーがありました。上記の解決策は機能しますが、それが修正されるはずの方法ではありません。Deviseのデフォルトルートには、DELETEメソッドとしてサインアウトルートがすでに含まれています。通常、デフォルトルート自体を変更する必要はありません。そのため、別link_toの回答で説明されているように、呼び出しに別のパラメーターを追加するだけで修正できます。
Jessie Dedecker、2011

route.rbファイルにルートを追加する必要はありません。deviseでは、/ confit / initializers /ディレクトリにあるdevise.rbのメソッドを変更できます。
Travis Pessetto、2011

6
GETとしてログアウトパスを持つことはありません。
Jagira

@ジャギラなぜ?削除と取得の両方をしないのはなぜですか?
hrdwdmrbl 2012年

14

あなたのroutes.rbファイルでそれを使用してください:

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

13

Rails 3.1.0でも同じ問題が発生し、次の行をファイルに追加して解決しました。

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

bowerを使用している場合は、// = require jquery-ujsを試してください。
モンテイロブレナ2015年

10

1つの例外を除いて、ジェシーの答えは私にとってうまくいきました:

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

変化する:

:delete

...から:

'delete'

だから私のために働いたコードは:

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

このコードスニペットを投稿していただき、ありがとうございます。sign_outが機能するようになりました。
2012年

9

質問に対する多くの回答はすでにあります。私にとっての問題は2つありました。

  1. ルートを拡大すると:

    devise_for :users do 
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
  2. これは減価償却されているという警告を受けていたので、次のものに置き換えました:

    devise_scope :users do
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
  3. 私はjQueryを削除すると思いました。下手な選択。DeviseはjQueryを使用してDELETEリクエストを「偽造」し、GETとして送信しています。したがって、次のことを行う必要があります。

    //= require jquery
    //= require jquery_ujs
  4. そしてもちろん、前に述べた多くのリンクと同じです:

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

3番目の点について説明してください。私はその被害者であり、もっと理解したいと思っています
Rahul Dess

1
もちろん。あなたのウェブサイトは本当にDELETEリクエストを送信していません。率直に言って、GETとPOSTのみを使用します。Railsコミュニティでは、(正当な理由により)DELETEリクエストを送信するときにレコードを削除することに同意しているため、少しトリックを使用する必要があります。ERBで指定する場合、method::delete railsはそれをHTML5タグに変換します:data-method = "delete"で、GETとして送信します。これが、jQuery-ujsとjQueryが関係する場所です。これにより、アプリがこれを実行していることを認識できます。リクエストをコントローラーのアクションと一致させることができます。
Lukasz Muzyka 2014

それらの宝石がなければ、これは機能しません。もちろん、(devise initialiserで)deviseの設定を変更して、DELETEの代わりにGETを使用するように依頼することもできます。
Lukasz Muzyka 2014

7

追加:

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

これらのlink_toタグを使用する

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

  or

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

ルートに追加:

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

7

その他のオプションは、ログアウトをDELETEではなくGETになるように構成することです。次の行を追加することで実行できます。 /config/initializers/devise.rb

config.sign_out_via = :get

しかし、Steve Klabnikが彼のブログ(http://blog.steveklabnik.com/2011/12/11/devise-actioncontroller-routingerror-no-route-matches-get-slash-users-slash-sign-out.html )このメソッドのセマンティクスのため、DELETEを使用してみてください。


Devise 3.5.1とRails 4.2.3では、この答えのみが機能しました
sagar junnarkar

サーバーの再起動を忘れないでください:)
jackmin

6

Rails 3.1を使用している場合は、application.html.erbのログアウトが次のようになっていることを確認してください。

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

そして、あなたのjavascript include行は次のようになります

<%= javascript_include_tag 'application' %>

私の推測では、一部のGemはdefault.jsの場所の新しい構造を上書きします。


ありがとう!これは私を夢中にさせました!
Dorian

5

githubのソースコードでそれをチェックしてください:

https://github.com/plataformatec/devise/commit/adb127bb3e3b334cba903db2c21710e8c41c2b40#lib/generators/templates/devise.rb (日付:2011年6月27日)

  • #リソースのサインアウトに使用されるデフォルトのHTTPメソッド。デフォルトは:getです。188
  • #config.sign_out_via =:get 187
  • #リソースのサインアウトに使用されるデフォルトのHTTPメソッド。デフォルトは:deleteです。188
  • config.sign_out_via =:delete

5

まあ、私にとっては:method =>:deleteを削除するだけでした

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

5

これは、jquery-rails gemをインストールした後でjqueryファイルを生成していないことを意味します。したがって、最初にそれを生成する必要があります。

rails generate devise:install

最初のオプション:

つまり、次の行を変更する必要があります。 /config/initializers/devise.rb

config.sign_out_via =:delete to config.sign_out_via =:get

2番目のオプション:

ビューファイルでこの行<%= link_to "Sign out", destroy_user_session_path %>を変更するだけ<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>です。

通常:method => :delete、デフォルトでは書き込まれません。


5

少し古いのに付け加えたい。

:method =>:deleteがあるにもかかわらず、「sign_out」リンクが機能しませんでした。

<%= javascript_include_tag :defaults %>含める必要があることを示すコメントは、最近JQuery Javaスクリプトを追加し、シンプルな<script src=""/>し、それらを含めるタグをた。

:defaultsの後から前に移動すると、sign_outが再び機能し始めました。

うまくいけば、これは誰かを助けます。


5

ほとんどの答えは部分的です。私はこの問題に何度も遭遇しました。2つのことに対処する必要があります。

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

削除メソッドを指定する必要があります

次にdeviseはjqueryを使用するため、それらをロードする必要があります

   <%= javascript_include_tag "myDirectiveJSfile" %> 

そして、jDirectとjquery-ujsの両方がmyDirectiveJSfile.jsで指定されていることを確認してください

//= require jquery
//= require jquery_ujs

5

application.jsに次の行を含めることを忘れないでください(Rails 3)

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

jquery_ujs私のRailsアプリケーションに含めると、それが動作します。


4

deviseでHTTPSを使用している場合、サインアウトリンクが非セキュアバージョンへのものであると、HTTPSは機能しなくなります。バックエンドでは、セキュアなバージョンにリダイレクトします。このリダイレクトはGETであり、問​​題が発生します。

リンクでHTTPSが使用されていることを確認してください。あなたはそれをprotocol: "https"あなたのURLヘルパーで強制することができます(あなたがパスヘルパーではなくURLヘルパーを使用することを確認してください)。

<%= 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

問題はrails 3.1から始まります... /app/assets/javascript/application.jsを探してください。

ファイルが存在しない場合は、その名前のファイルを作成します。ファイルが表示されない、またはで作成されなかった理由がわかりません"rails new app"...

そのファイルはのインスタンスですjquery...


3

ソリューションはたくさんあります。しかし、ほとんどこれを使用し、

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

または適切なsign_outメソッドを使用したdevise.rbの構成

devise.rb

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

3

パスの使用:get:delete方法:

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

注:これとは別に宣言されたdevise_for:usersが必要です。dipole_momentからの回答を参照してください。
テイラードWebサイト

2

あなたのroutes.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

そしてあなたのapplication.html.erbで:

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

1
構文は次のとおりです:devise_for:users次にgetをdevise_scope:user doに配置する必要があります注:singular:user for devise_scope
Taylored Web Sites

2

これは私がしたことです(Rails 3.0とDevise 1.4.2で):

  1. ページにrails.jsが読み込まれていることを確認します
  2. このパラメータを使用: 'data-method' => 'delete'
  3. このパラメータを追加することをお勧めします::rel => 'nofollow'

1

"devise_for:users"の前に、routes.rbに "resource:users"があるかどうかを確認し、それらをスワップしてみます。

  1. 作品

    • devise_for:users
    • リソース:ユーザー
  2. 失敗する

    • リソース:ユーザー
    • devise_for:users

1

':method => :delete「のページにある」data-method="delete"あなたのページがjquery_ujs.jsを持っている必要がありますので、それはメソッドgetを削除しませ方法でリンクを提出します"


1

これはRails 3に基づく古い質問であることは知っていますが、Rails 4.0.4で問題を解決しました。このバージョンでこの問題に遭遇した人のために、私がそれをどのように修正するかを提案したいと思いました。あなたの走行距離は異なる場合がありますが、ここで私のために働いたものです。

まず、gemがインストールされていることを確認し、bundle installを実行します。

gem 'jquery-rails'

gem 'turbolinks'

gem 'jquery-turbolinks'

application.jsで、以下のようにすべてが必要であることを確認します。

この落とし穴場合は注意してください:それはだ//= require jquery.turbolinksとありません//= require jquery-turbolinks

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

次に、application.html.erbのヘッダーに適切なリンクを追加します。

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

使用しているRailsのバージョンに応じて、私が削除メソッドを実装する方法には多くのバリエーションがあるようです。これはdelete私が使用した構文です。

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

この非常にイライラする穴から誰かを掘り出すのに役立つことを願っています!


0

一般に、「一致するルートはありません」というメッセージが表示されたが、そのルートが定義されていると思われる場合は、そのルートのhttp動詞/リクエストメソッド(その取得、書き込み、投稿、削除など)を再確認します

レイクルートを実行すると、予想されるメソッドが表示され、これをリクエストログと比較できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.