"/ users / sign_out"고안 레일 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
예. 안전을 위해 다시 해냈습니다. 또한 Stacks의 다른 곳에서 Rails 3.0.3과 호환되지 않는 최신 고안 보석과 관련된 문제 일 수 있으므로 고안 보석을 1.4.2에서로 변경하려고했습니다 gem 'devise', :git => 'git://github.com/plataformatec/devise.git'. 그래도 아무것도하지 않았다.
vich

Gemfile에서 항목을 변경하지 않아도 최신 버전의 Devise를 얻을 수 있습니까? 더 낮은 버전 번호를 지정해 보셨습니까?
레오 Cassarani

route.rb 파일을 게시 할 수 있습니까
felix

1
Jessie의 두 번째 답변은 완벽하게 작동했습니다.
vich

답변:


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항상 나를 위해 충분히 좋았습니다.
레오 Cassarani

8
나는 테스트를했고 그것은 나를 위해 작동합니다. 일이 한 버전에서 다른 버전으로 바뀌는 것을 잊지 마십시오 (Rails 또는 Devise에서). 또한 로그 아웃은 상태 변경 동작으로 GET 방법을 사용해서는 안됩니다 (내 겸손한 견해).
Jessie Dedecker

23
자세한 내용은 최신 버전의 Devise에서 변경된 이유에 대한 근거는 여기여기에 설명 되어 있습니다 .
Jessie Dedecker

6
나는이 같은 문제에 부딪 쳤고 Jessie의 제안은 나를 위해 일했다. 나는 ... 유증의 railscast 통해 실행하는 사람이 결국 인해이 변경에 여기까지 기대
johnnygoodman

2
$("<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"을 사용하여 로그 아웃했지만 "DELETE"로 변경하여보다 편안하게 만들었습니다. 저자는 GET이 로그 아웃과 같은 서버를 변경해서는 안된다고 설명했다.
Jonathan Allard

2
이것은 나를 위해 일했습니다. 최선의 방법은 아니지만 다른 답변은 실패했습니다. 왜 그런지 알 수 없습니다 !!
Mild Fuzz

8
여러 방법을 지원하려는 경우 배열을 사용할 수도 있습니다. 예를 들어 , devies / rails / routes.rb에 설명 된대로 config.sign_out_via = [ :post, :delete ]또는 . devise_for :users, :sign_out_via => [ :post, :delete ]
Hosam Aly

2
XSRF 공격에 사용자를 열 때 GET 요청을 사용하여 로그 아웃하지 않습니다. (해커는 src = " foo.com/users/sign_out "을 사용 하여 이미지 태그가있는 웹 사이트를 만들고 사용자가 해당 웹 사이트를 방문하여 로그 아웃합니다.
라이언 도허티

1
@RyanDoherty ID 실수하지 않습니다. XSRF는 여전히 가능합니다 (공격자는 대상 URL에서 action = "DELETE"형식을 사용한 다음 페이지로드시 자동 제출해야합니다).
Maël Nison

60

jquery_ujs 자바 스크립트 파일을 포함하지 않았을 수 있습니다. 최신 버전의 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-style) 에 설명 된대로 링크를 추가하십시오 .

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

그리고 모든 것이 잘 될 것입니다.


8
내 link_to에 : method => 'delete'가 있습니다. 문제는 jquery_ujs가 포함되어 있지 않습니다.이 솔루션은 내 문제를 해결했습니다. gem 'jquery-rails'를 gemfile에 넣어야합니다.
Rob Bazinet

2
고마워 이것은 나를 위해 일했다. 기본값을 사용하는 대신 사용할 수도 있습니다javascript_include_tag "jquery_ujs"
Bnicholas

잘 잡아라, 고마워! require.js를 사용하여 파일을 비동기 적으로로드하고 jquery_ujs가 필요하지 않았습니다.
Dan Fairaizl

"u"는 압축되지 않은 것을 의미한다고 가정하고에서이 줄을 제거했습니다 application.js. 나쁜 가정입니다. 감사.
Jeff

이 문제는 트위터 부트 스트랩을 적은 것에서 sass로 변경 한 후 (100 번째 devise 기반 응용 프로그램에서) 자랐으며 // = require jquery_ujs를 내 application.js에 다시 추가하는 것을 잊었습니다.

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). With button_toRails는 적절한 DELETE 호출을 위해 많은 노력을 기울일 것입니다. 그런 다음 원하는 경우 링크처럼 보이도록 단추의 스타일을 지정할 수 있습니다.

link_to에서 button_to 로의 변경이 나를 위해 일했지만 실제로 이유를 이해하지 못합니까? html / css와 정확히 다른 점은 무엇입니까?
Spyros Mandekis

1
button_to 및 link_to와 같은 기능에서 HTML을 자동 생성하는 레일 '매직'과 관련이 있습니다. button_to에 대한 rails magic은 적절한 RESTful DELETE 호출을 지정하고 link_to는 그렇지 않습니다. 추측해야한다면, html 버튼 요소가 DELETE 호출 (또는 액션을 지정하는 숨겨진 필드가있는 번들)을 처리 할 수 ​​있지만 일반 링크는 처리 할 수 ​​없기 때문입니다.
윌 나단

고마워 jquery를 수동으로 처리하도록 앱을 설정했기 때문에 jquery-uj가 없었습니다. 바우어 또는 번 들러로 설치하고 자산 파이프 라인에 적절한 라인을 포함하면 문제가 해결됩니다.
jrhorn424

1
이것은 나에게 가장 안전하고 휴대용 솔루션입니다.

에 대해 button_toRails form는 전체 작업에 대해를 생성합니다 . 이 사용 가능한 이유하다고 :delete과 방법 button_to이 아니라으로 link_to, 단지 생성 된 HTML을 참조하십시오.
Fernando Fabreti

25

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

route.rb 파일에 경로를 추가 할 필요가 없습니다. devise를 사용하면 / confit / initializers / 디렉토리에있는 devise.rb의 메소드를 변경할 수 있습니다.
Travis Pessetto

6
절대로 GET으로 로그 아웃 경로가 없습니다.
Jagira

@Jagira 왜? 왜 DELETE와 GET을 사용하지 않습니까?
hrdwdmrbl


13

rails 3.1.0과 같은 문제가 있었고 파일에 다음 줄을 추가하는 것을 해결했습니다.

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

bower를 사용한다면 // = jquery-ujs를 요구하십시오.
monteirobrena

10

한 가지 예외를 제외하고 Jessie의 대답은 저에게 효과적이었습니다.

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

변화:

:delete

...에서 :

'delete'

그래서 나를 위해 일한 코드는 다음과 같습니다.

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

이 코드 스 니펫을 게시 해 주셔서 감사합니다. sign_out은 저에게 효과적입니다.
buk

9

질문에 대한 많은 답변이 이미 있습니다. 나에게 문제는 두 가지였다.

  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 point..i을 설명 할 수있는 그것의 피해자 였고, 내가 더 이해하려는
라훌에 데스

1
확실히. 귀하의 웹 사이트는 실제로 DELETE 요청을 보내지 않습니다. 솔직히 GET과 POST 만 사용합니다. Rails 커뮤니티에서는 (좋은 이유로) DELETE 요청을 제출할 때 레코드를 삭제하고 싶다는 데 동의했기 때문에 약간의 트릭을 사용해야합니다. ERB에 메소드를 지정하면 : delete rails가이를 HTML5 태그 (data-method = "delete")로 변환하고 GET으로 제출합니다. 이제 jQuery-ujs와 jQuery가 시작됩니다. 앱이이를 인식하고 있습니다. 따라서 귀하의 요청을 컨트롤러 작업과 일치시킬 수 있습니다.
Lukasz Muzyka

그 보석이 없으면 작동하지 않습니다. 물론 고안의 설정을 고안하고 (초기 고안자에서) DELETE 대신 GET을 사용하도록 요청할 수 있습니다.
Lukasz Muzyka

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
효과가있었습니다

서버를 다시 시작하는 것을 잊지 마십시오 :)
jackmin

6

Rails 3.1을 사용하는 경우 application.html.erb 로그 아웃이 다음과 같은지 확인하십시오.

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

그리고 자바 스크립트 포함 줄은 다음과 같습니다

<%= javascript_include_tag 'application' %>

내 생각에 일부 보석은 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 = : 삭제

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 = : 삭제 삭제 config.sign_out_via = : get

두 번째 옵션 :

보기 파일 에서만이 줄 <%= 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

대부분의 답변은 부분적입니다. 나는이 문제를 여러 번 맞았습니다. 다음 두 가지 사항을 해결해야합니다.

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

삭제 방법을 지정해야합니다

그런 다음 devise는 jquery를 사용하므로로드해야합니다.

   <%= javascript_include_tag "myDirectiveJSfile" %> 

그리고 jQuery와 jquery-ujs가 myDirectiveJSfile.js에 지정되어 있는지 확인하십시오.

//= require jquery
//= require jquery_ujs

5

application.js에 다음 줄을 포함시키는 것을 잊지 마십시오 (Rails 3)

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

jquery_ujs레일 애플리케이션에 포함 하면 이제 작동합니다.


4

당신이 사용하는 경우 유증으로 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 메소드를 사용하여 config 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의 답변을 참조하십시오.
Taylored 웹 사이트

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 그러면 가져 오기를 devise_scope : user do에 두어야합니다. 참고 : devise_scope에 대한 singleular : user
Taylored 웹 사이트

2

이것이 내가 한 일입니다 (Rails 3.0 및 Devise 1.4.2로).

  1. 페이지가 rails.js를로드하는지 확인하십시오
  2. 이 매개 변수를 사용하십시오 : 'data-method'=> 'delete'
  3. 이 매개 변수를 추가하는 것이 좋습니다 : : rel => 'nofollow'

1

route.rb에 "devise_for : users"앞에 "resource : users"가 있는지 확인한 후 스왑을 시도하십시오.

  1. 공장

    • devise_for : 사용자
    • 자원 : 사용자
  2. 실패

    • 자원 : 사용자
    • devise_for : 사용자

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 동사 / 요청 방법 (get, put, post, delete 등)을 다시 확인하십시오 .

레이크 경로를 실행하면 예상 된 방법이 표시되며이를 요청 로그와 비교할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.