[英]Different '/' root path for users depending if they are authenticated (using devise)
I'm writing a rails app in which I have an Editor and a Publication model. 我正在编写一个rails应用程序,其中我有一个编辑器和一个出版物模型。 I'm using devise for editors authentication and, since an editor can't do anything as guest, I wrote a custom layout to use for the login page and I want that a guest user can see only the login page.
我正在使用设计编辑器身份验证,并且由于编辑器不能作为访客执行任何操作,我编写了一个用于登录页面的自定义布局,我希望访客用户只能看到登录页面。
Now I'm trying to achieve the following behavior in my app but unsuccessfully: 现在,我正在尝试在我的应用程序中实现以下行为,但未成功:
require 'spec_helper'
require 'capybara/rails'
describe "Authentication" do
describe "when logged in" do
before(:each) do
@editor = Factory(:editor, :password => 'secret')
visit '/'
fill_in 'Login', :with => @editor.login
fill_in 'Password', :with => 'secret'
click_button 'Sign in'
page.should have_content('Signed in successfully.')
end
it "getting / should render publication page with no redirection" do
visit '/'
page.should_not have_content('Login')
page.should have_content('Publications')
# assert that there is no redirection
page.current_path.should == '/'
end
it "visits the sign_in page should redirect to /" do
visit '/editors/sign_in'
page.should have_content('Publications')
page.current_path.should == '/'
end
end
describe "when not logged in" do
it "getting / should not display the sign in warning" do
visit '/'
# I want to get rid of this message
page.should_not have_content('You need to sign in or sign up before continuing.')
end
it "getting / should not redirect to the sign_in default page" do
visit '/'
page.should have_content('Login')
# assert that there is no redirection
page.current_path.should == '/'
end
it "getting the the sign_in default path works" do
visit '/editors/sign_in'
page.should have_content('Login')
page.current_path.should == '/editors/sign_in'
end
it "login works and redirect me to the publications page (with /)" do
@editor = Factory(:editor, :password => 'secret')
visit '/'
fill_in 'Login', :with => @editor.login
fill_in 'Password', :with => 'secret'
click_button 'Sign in'
page.should have_content('Signed in successfully.')
page.current_path.should == '/'
page.should have_content('Publications')
end
end
end
The main issue is that I want to get rid of 'You need to sign in or sign up before continuing.' 主要问题是我想摆脱“你需要在继续之前登录或注册”。 message when a guest user visit '/'.
访客用户访问'/'时的消息。
I tried with hints taken from here and here but with no luck. 我尝试了从这里和这里采取的提示,但没有运气。
Any hint on how implement this with devise? 有关如何实现此设计的任何提示?
Thanks. 谢谢。
I think you should use something like that 我认为你应该使用类似的东西
authenticated :user do
root :to => 'users#index', as: :authenticated_root
end
root :to => 'welcome#index'
since rails4 doesn't allow routes with same name you need to specify as: 由于rails4不允许具有相同名称的路由,因此需要指定为:
This post explain how to achieve that: 这篇文章解释了如何实现:
authenticated :user do
root :to => "main#dashboard"
end
root :to => "main#index"
Here is the pull request which implement this with some technical details 以下是执行此操作的pull请求以及一些技术细节
authenticated :user do
root :to => 'home#index', :as => :authenticated_root
end
root :to => redirect('/users/sign_in')
Straight from the horse's mouth at the How to's for the devise gem . 直接来自马的嘴巴, 如何为设计宝石 。 :D
:d
Also because of you need to name these root paths in Rails 4 you might find that it is annoying when you want to just use root_path on say your logo to take you back to the dashboard or homepage respectively. 另外,由于您需要在Rails 4中命名这些根路径,您可能会发现当您想要使用root_path代表您的徽标分别将您带回仪表板或主页时,这很烦人。 I just created helpers in the ApplicationHelper that solves that easily.
我刚刚在ApplicationHelper中创建了帮助器,可以轻松解决这个问题。
module ApplicationHelper
def root_path
if user_signed_in?
authenticated_root_path
else
unauthenticated_root_path
end
end
def root_url
if user_signed_in?
authenticated_root_url
else
unauthenticated_root_url
end
end
end
Yeah, this issue was really frustrating for me as well. 是的,这个问题对我来说真的很令人沮丧。
Ultimately I ended up just hiding the flash message on the sessions#new page. 最后,我最终只是在会话#new页面上隐藏了flash消息。 Not a great solution at all since sometimes you /do/ want that message to show up..
根本不是一个很好的解决方案,因为有时你/做/希望该消息出现..
I gave up after a while, but I wonder if you could use this approach , but set some flag inside that lambda and have a before_filter in your sessions controller that empties flash if it's present. 我放弃了一段时间,但我想知道你是否可以使用这种方法 ,但在lambda中设置一些标志,并在会话控制器中有一个before_filter,如果它存在则清空闪存。 Something like...
就像是...
#routes
=> 'users#dashboard', :constraints => lambda {|r| r.env["skip_flash"] = true; r.env["warden"].authenticate? }
#sessions_controller.rb
before_filter :only=>[:new] do
flash[:notice] = nil if request.env["skip_flash"]
request.env["skip_flash"] = false
end
I'm not too familiar with how the routes constraint and the request object work.. but just an idea. 我不太熟悉路由约束和请求对象如何工作......但只是一个想法。 This would turn off the flash message only when you're trying to access the "/" and not other pages..
只有在您尝试访问“/”而不是其他页面时,才会关闭Flash消息。
I hope somebody has a nice solution! 我希望有人有一个很好的解决方案!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.