"/ Users / sign_out" ile eşleşen güzergah eşleşmiyor ray 3


386

Uygulamama cihaz geliştirdim ve aşağıdakileri uyguladım 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>

Koştum rake routes ve tüm yolları geçerli olduğunu doğruladı.

Ayrıca, routes.rbdosyamda vardevise_for :users ve root :to => "home#index".

"Oturumu kapat" bağlantısını tıkladığınızda aşağıdaki yönlendirme hatasını alıyorum:

No route matches "/users/sign_out"

Hataya neden olan herhangi bir fikir var mı?


1
Rotaları ekledikten sonra uygulamanızı yeniden başlattınız mı? Rota değişiklikleri sadece başlangıçta etkili olur.
Thilo-Alexander Ginkel

2
Evet. Sadece güvenli olmak için tekrar yaptım. Ayrıca, ben Rails 3.0.3 ile uyumlu olmayan yeni devise mücevher ile ilgili bir sorun olabilir Stack üzerinde başka bir yerde okudum, bu yüzden 1.4.2 için benim devise taş değiştirmeye çalıştı gem 'devise', :git => 'git://github.com/plataformatec/devise.git'. Yine de hiçbir şey yapmadı.
vich

Gemfile'daki girişi değiştirmek size daha yeni bir Devise sürümü getirmez mi? Daha düşük bir sürüm numarası belirtmeyi denediniz mi?
Leo Cassarani

Route.rb dosyanızı gönderebilir misiniz
felix

1
Jessie'nin aşağıdaki ikinci cevabı mükemmel çalıştı.
vich

Yanıtlar:


568

Oturumu kapatma yolunun bir DELETEyöntem olduğunu düşünüyorum . Bu, çıkış bağlantınızın aşağıdaki gibi görünmesi gerektiği anlamına gelir:

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

Seninki :method => :deleteparçayı içermiyor . Ayrıca, bunun çalışması <%= javascript_include_tag :defaults %>için mizanpaj dosyanıza da ( application.html.erb) eklemeniz gerektiğini lütfen unutmayın .


3
Rails uygulamamın hiçbirinde bunu yapmak zorunda olmadığımı güvenle söyleyebilirim. link_to "Sign out", destroy_user_session_pathbenim için her zaman yeterince iyi oldu.
Leo Cassarani

8
Testi yaptım ve benim için çalışıyor. İşlerin bir sürümden diğerine değiştiğini unutmayın (Rails veya Devise'da olsun). Ayrıca, çıkış yapmak GET yöntemleri (mütevazi görüşüme göre) kullanılarak yapılmaması gereken durum değiştiren davranıştır.
Jessie Dedecker

23
Daha fazla bilgi için, bunun Devise'nin en son sürümünde neden değiştirildiğinin gerekçesi burada ve burada açıklanmaktadır .
Jessie Dedecker

6
Aynı sorunla karşılaştım ve Jessie'nin önerisi benim için çalıştı. Ben devise railscast çalışan herkesin sonunda bu değişiklik nedeniyle burada sona ermesini bekliyoruz ...
johnnygoodman

2
bunu test etmek için web konsolunuza da yazabilirsiniz $("<a href='/users/sign_out' data-method='delete'>Sign out</a>").appendTo('body');- sayfada jQuery yüklüyse.
mraaroncruz

133

Bu satırı devise.rb'de değiştirdim:

config.sign_out_via = :delete

için

config.sign_out_via = :get

ve benim için çalışmaya başladı.


22
Daha önce yapıldığı yol "GET / users / sign_out" kullanarak oturumu kapatmaktı, ancak daha RESTful yapmak için "DELETE" olarak değiştirdiler. Yazar, bir GET'in sunucuda oturumu kapatmak gibi değişiklikler yapmaması gerektiğini açıkladı.
Jonathan Allard

2
bu benim için çalıştı. Bunun en iyi uygulama olmadığını takdir etsem de, diğer cevaplar başarısız oldu. Nedenini göremiyorum !!
Hafif Fuzz

8
Birden fazla yöntemi desteklemek istiyorsanız bir dizi kullanmak da mümkündür. Örneğin: config.sign_out_via = [ :post, :delete ]veya devise_for :users, :sign_out_via => [ :post, :delete ], devise / rails / route.rb .
Hosam Aly

2
Kullanıcıyı bir XSRF saldırısına kadar açtığı için oturumu kapatmak için bir GET isteği kullanmazdım. (Hacker, src = " foo.com/users/sign_out " ile resim etiketi içeren bir web sitesi oluşturur , kullanıcı siteyi ziyaret eder ve oturumu kapatır ).
Ryan Doherty

1
@RyanDoherty Id Yanılmıyorum, XSRF hala mümkündür (saldırganın hedef url'de action = "DELETE" olan bir form kullanması ve ardından sayfa yüklemesinde otomatik olarak göndermesi gerekir).
Maël Nison

60

Muhtemelen jquery_ujs javascript dosyasını eklemediniz. Jquery-ujs'un en son sürümünü kullandığınızdan emin olun: https://github.com/rails/jquery-ujs ve mevcut son dosyalar:

rails generate jquery:install

Sen gerektiğini değil artık rails.js dosyası var. Eğer yaparsanız, muhtemelen güncel değilsiniz demektir. Bu dosyanın ayrıca config / application.rb dosyasında varsayılanlarla yüklendiğinden emin olun.

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

(Yine, gereken değil burada rails.js dosyası var). Son olarak, bağlantıyı Devise wiki'de (haml tarzı) belgelendiği şekilde ekleyin :

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

Ve her şey iyi olacak.


8
Ben vardı: method => 'delete' benim link_to, sorun jquery_ujs dahil değildi, bu çözüm benim sorunum çözüldü. Gem'inize mücevher 'jquery-rails' koymayı unutmayın.
Rob Bazinet

2
Teşekkürler bu benim için çalıştı. Varsayılanları kullanmak yerine şunları da kullanabilirsinizjavascript_include_tag "jquery_ujs"
Bnicholas

İyi yakaladın, teşekkürler! Dosyaları senkronize olmayan bir şekilde yüklemek için requir.js kullanıyorum ve jquery_ujs gerektirmeyi unuttum.
Dan Fairaizl

"U" nun sıkıştırılmamış anlamına geldiği ve bu satırın kaldırıldığını varsaydım application.js. Sanırım kötü varsayım. Teşekkürler.
Jeff

Bu sorun twitter bootstrap sass az değiştirdikten sonra (benim 100th tabanlı tabanlı app) kırpılmış ve benim uygulama.js içine // = gerektirir jquery_ujs eklemek unuttum.
Joe

31

Oturumu Kapat bağlantısını RESTful çağrısını silme yeteneği data-method = "delete", rails kodunu kullanarak bir html özniteliği gerektirir = link_to('Logout', destroy_user_session_path, :method => :delete).

Ancak, geminiz jquery-ujsyüklü değilse veya application.html dosyasında ortaya çıkan javascript'i çağırmıyorsanız,= javascript_include_tag "application" , yanıt bir GET isteği olarak gönderilir ve rota başarısız olur.

Kullanmak istemiyorsanız jquery-ujsveya çalışmasını sağlayacak bir yol bulamıyorsanız birkaç seçeneğiniz vardır :

  1. Içinde config.sign_out_viaeşit olarak değiştirin (DELETE uygun RESTful sorgusu olduğundan önerilmez):getdevise.rb
  2. YA Değişim link_toiçin = button_to('Logout', destroy_user_session_path, :method => :delete). İle button_toRaylar doğru SİL çağrı yapmaya ağır işi yapacağız. İsterseniz düğmeyi bir bağlantı gibi görünecek şekilde şekillendirebilirsiniz.

Link_to'dan button_to'ya geçiş benim için çalıştı, ama gerçekten nedenini anlamıyorum? Html / css dışında tam olarak ne değişti?
Spyros Mandekis

1
Bu, button_to ve link_to gibi işlevlerden otomatik olarak html üreten raylar 'magic' ile ilgilidir. Sadece öyle olur ki button_to için rails magic doğru RESTful DELETE çağrısını belirtir ve link_to bunu belirtmez. Tahmin etmek zorunda kalsaydım, bunun nedeni, normal bağlantılar yapamazken html düğmesi öğelerinin bir DELETE çağrısını (veya eylemi belirten gizli bir alanla birlikte) işleyebileceğini söyleyebilirim.
Nathan

Bunun için teşekkürler. Benim app jquery elle işlemek için kurulum, bu yüzden jquery-ujs yoktu. Bower veya bundler ile kurmak ve varlık boru hattı için uygun hattı dahil etmek sorunu çözer.
jrhorn424

1
Bu bana en güvenli ve en taşınabilir çözüm gibi geliyor.

Hakkında button_to, Rails formtüm eylem için bir üretir . Bu nedenle :deleteyöntemi kullanarak button_todeğil de kullanmak mümkündür link_to, sadece oluşturulan HTML'yi görün.
Fernando Fabreti

25

Tasarlamak / oturumlar # için yeni bir rota eklemeyi ve buna bağlanmayı deneyin. Örneğin:

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

görünüm:

<%= link_to "Logout", logout_path %>

Mmichael ile aynı hatayı alıyorum. Yukarıdaki test benim için çalışıyor.
rtfminc

1
Ayrıca mmichael ile aynı hatayla karşılaştım. Yukarıdaki çözüm işe yarayacaktır, ancak bunun nasıl düzeltileceği söz konusu değildir. Devise'deki varsayılan yollar zaten çıkış yolunu bir DELETE yöntemi olarak içerir. Normalde varsayılan yolları kendiniz değiştirmeniz gerekmez. Bu nedenle link_to, diğer cevapta açıklandığı gibi , çağrıya ayrı bir parametre ekleyerek düzeltebilirsiniz .
Jessie Dedecker

Route.rb dosyasına bir rota eklemeniz gerekmez, devise / confit / initializers / dizinindeki devise.rb içindeki yöntemi değiştirmenize izin verir.
Travis Pessetto

6
Asla GET olarak çıkış yolunuz yok.
Jagira

@Jagira neden? Neden hem DELETE hem de GET olmasın?
22:12

14

Route.rb dosyanızda kullanın:

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

13

Ben 3.1.0 raylar ile aynı sorunu vardı ve aşağıdaki satırları dosyaya ekleme çözüldü:

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

Bower kullanıyorsanız // = jquery-ujs gerektirir.
monteirobrena

10

Bir istisna dışında Jessie'nin yanıtı benim için çalıştı:

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

değişiklik:

:delete

... için:

'delete'

Yani benim için çalışan kod:

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

Bu kod snippet'ini gönderdiğiniz için teşekkür ederiz, sign_out benim için çalışıyor.
buk

9

Sorunun cevabı zaten. Benim için sorun iki kattı:

  1. rotalarımı genişlettiğimde:

    devise_for :users do 
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
  2. Bu amortisman uyarısı alıyordum, bu yüzden onu değiştirdim:

    devise_scope :users do
       get '/users/sign_out' => 'devise/sessions#destroy'
    end
  3. JQuery'mi kaldıracağımı düşündüm. Kötü seçim. Devise, isteği SİL "sahte" jQuery kullanıyor ve GET olarak gönderiyor. Bu nedenle şunları yapmanız gerekir:

    //= require jquery
    //= require jquery_ujs
  4. ve elbette daha önce bahsedilen birçok bağlantı ile aynı bağlantı:

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

3ncü noktayı açıklayabilir misin ... ben onun kurbanıydım ve daha fazla anlamak istiyorum
Rahul Dess

1
Kesinlikle. Web siteniz gerçekten herhangi bir DELETE isteği göndermiyor. Açıkçası sadece GET ve POST kullanacaktır. Rails topluluğunda, DELETE isteği gönderilirken (iyi nedenlerle) kayıtları silmek istediğimizde küçük bir numara kullanmamız gerektiği kabul edildi. ERB'nizde yöntem belirttiğinizde:: delete rayları bunu HTML5 etiketine dönüştürür: data-method = "delete" ve GET olarak gönderir. Şimdi, bu jQuery-ujs ve jQuery devreye giriyor. Onlar app ne yaptığınızı tanımasına izin veriyorlar. Böylece talebiniz denetleyici eylemiyle eşleştirilebilir.
Lukasz Muzyka

bu taşlar olmadan, bu işe yaramaz. Tabii ki, cihazın ayarlarını değiştirebilir (cihaz başlatıcısında) ve ondan DELETE yerine GET'i kullanmasını isteyebilirsiniz.
Lukasz Muzyka

7

Ekle:

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

Bu link_to etiketlerini kullanın

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

  or

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

Rotalarda ekleyin:

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

7

Diğer seçenek, oturum kapatmanın bir DELETE yerine bir GET olacak şekilde yapılandırılmasıdır, bunu aşağıdaki satırı ekleyerek yapabilirsiniz /config/initializers/devise.rb

config.sign_out_via = :get

Ancak Steve Klabnik'in blogunda yazdığı gibi (http://blog.steveklabnik.com/2011/12/11/devise-actioncontroller-routingerror-no-route-matches-get-slash-users-slash-sign-out.html ) bu yöntemin semantiği nedeniyle DELETE işlevini kullanmaya çalışın.


Devise 3.5.1 & Rails 4.2.3 için sadece bu cevap işe yaradı
sagar junnarkar

Sunucuyu yeniden başlatmayı unutma :)
jackmin

6

Rails 3.1 kullanıyorsanız application.html.erb çıkışınızın aşağıdaki gibi olduğundan emin olun:

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

Javascript içerme satırınız aşağıdaki gibi görünüyor

<%= javascript_include_tag 'application' %>

Tahminimce bazı taşlar default.js konumunun yeni yapısının üzerine yazılır.


Teşekkürler! Bu beni deli ediyordu!
Dorian


5

Eh, çocuklar benim için sadece kaldırmak: yöntem =>: delete

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

5

Bu, jquery-rails gemini kurduktan sonra jquery dosyalarını oluşturmadığınız anlamına gelir. Yani önce onu oluşturmanız gerekiyor.

rails generate devise:install

İlk seçenek:

Bu, aşağıdaki satırı değiştirmeniz gerektiği anlamına gelir /config/initializers/devise.rb

config.sign_out_via =: silme config.sign_out_via =: al

İkinci seçenek:

Yalnızca bu hattı değiştirmek <%= link_to "Sign out", destroy_user_session_path %>için <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>görünümü dosyada.

Genellikle :method => :deletevarsayılan olarak yazılmaz.


5

Biraz eski olmasına rağmen buna eklemek istiyorum.

"sign_out" bağlantısı şu yöntemlere rağmen çalışmadı: method =>: delete.

<%= javascript_include_tag :defaults %>Dahil edilmesi gerektiğini belirten yorum bana yakın zamanda JQuery java komut dosyası ekledi ve <script src=""/>bunları dahil etmek için basit etiketleri kullandığımı hatırlattı .

Onları: varsayılanlarından daha öncesine taşıdığımda, sign_out tekrar çalışmaya başladı.

Umarım bu birine yardımcı olur.


5

Cevapların çoğu kısmi. Bu konuyu defalarca vurdum. İki şey ele alınmalıdır:

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

silme yönteminin belirtilmesi gerekir

Sonra devise jquery kullanır, bu yüzden bunları yüklemeniz gerekir

   <%= javascript_include_tag "myDirectiveJSfile" %> 

ve myDirectiveJSfile.js dosyanızda İKİ jquery ve jquery-ujs belirtildiğinden emin olun

//= require jquery
//= require jquery_ujs

5

Application.js dosyasına aşağıdaki satırı eklemeyi unutmayın (Rails 3)

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

jquery_ujsBenim raylar uygulaması içine dahil ve şimdi çalışıyor.


4

HTTPS'yi geliştirici ile kullanıyorsanız , çıkış bağlantınız güvenli olmayan sürüme ise devre dışı kalır. Arka uçta, güvenli sürüme yönlendirilir. Bu yönlendirme, soruna neden olan bir GET'tir.

Bağlantınızın HTTPS kullandığından emin olun. protocol: "https"URL yardımcısıyla zorlayabilirsiniz (yol yardımcısını değil, url yardımcısını kullandığınızdan emin olun).

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

Sorun raylar 3.1 ile başlar ... /app/assets/javascript/sadece application.js arayın.

Dosya yoksa, bu adda bir dosya oluşturun "rails new app".... Dosyamın neden kaybolduğunu veya hiçbir zaman oluşturulmadığını bilmiyorum .

Bu dosya bunun örneğidir jquery....


3

Birçok çözüm var. ama çoğunlukla bunu kullanın,

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

veya devise.rb dosyasını uygun sign_out yöntemiyle yapılandırın

Devise.rb içinde

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

3

yolunuz için kullanım :getve :deleteyöntem:

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

Not: bundan ayrı olarak bildirilen devise_for: kullanıcıları olmalıdır. dipole_moment'in cevabına bakınız.
Taylored Web Siteleri

2

Route.rb dosyasında:

 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

ve application.html.erb dosyasında:

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

1
Sözdizimi şimdi: devise_for: kullanıcılar sonra devise_scope koymak gerekir: user do NOT: tekil: devise_scope için kullanıcı
Taylored Web Siteleri

2

(Rails 3.0 ve Devise 1.4.2 ile) bunu yaptım:

  1. Sayfanızın rails.js yüklediğinden emin olun
  2. Bu parametreyi kullanın: 'data-method' => 'delete'
  3. Bu parametreyi eklemek iyi fikir:: rel => 'nofollow'

1

Route.rb dosyanızın "devise_for: users" ifadesinden önce bir "kaynak: kullanıcıları" olup olmadığını görün, sonra bunları değiştirmeyi deneyin:

  1. İşler

    • devise_for: kullanıcılar
    • kaynaklar: kullanıcılar
  2. başarısız

    • kaynaklar: kullanıcılar
    • devise_for: kullanıcılar

1

':method => :delete'sayfasında ise' data-method="delete"sayfanızın jquery_ujs.js olmalı 'böylece, bu yöntemin silemezsiniz yöntem olsun bağlantıyı sunacaktır


1

Bu Rails 3 tabanlı eski bir soru olduğunu biliyorum ama ben sadece Rails 4.0.4 üzerinde koştu ve çözdü. Bu yüzden bu sürümde bu sorunla karşılaşan herkes için nasıl düzeltebileceğimi düşündüm. Kilometreniz değişebilir ama benim için işe yarayan şey bu.

Öncelikle mücevherlerin kurulu olduğundan ve paket kurulumunu çalıştırdığınızdan emin olun.

gem 'jquery-rails'

gem 'turbolinks'

gem 'jquery-turbolinks'

Application.js dosyasında aşağıdaki gibi her şeyin gerekli olup olmadığını kontrol edin.

Bu yakalandığına dikkat edin : öyle //= require jquery.turbolinksve değil//= require jquery-turbolinks

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

Ardından, application.html.erb başlığına uygun bağlantıları ekleyin.

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

Kullandığınız Rails sürümüne bağlı olduğunu düşündüğüm silme yönteminin nasıl uygulanacağına dair birçok varyasyon var. Bu deletebenim kullandığım sözdizimidir.

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

Umarım bu çok sinir bozucu delikten birini kazmaya yardımcı olur!


0

Genel olarak "Güzergah eşleşmesi yok", ancak bu güzergahın tanımlandığını düşündüğünüzde, o güzergah için http fiil / istek yöntemini (get, put, post, delete vb.) İki kez kontrol edin. .

Komisyon yolları çalıştırırsanız, beklenen yöntemi görürsünüz ve bunu istek günlüğü ile karşılaştırabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.