用户的不同'/'根路径,具体取决于它们是否经过身份验证(使用设计)

时间:2011-04-20 03:09:14

标签: ruby-on-rails routes devise

我正在编写一个rails应用程序,其中我有一个编辑器和一个出版物模型。我正在使用devise进行编辑器身份验证,并且由于编辑器不能作为guest用户执行任何操作,因此我编写了一个用于登录页面的自定义布局,并且我希望guest用户只能看到登录页面。

现在我正在尝试在我的应用中实现以下行为,但未成功:

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

主要问题是我想摆脱'你需要在继续之前登录或注册。'访客用户访问'/'时的消息。

我尝试了从herehere获取的提示,但没有运气。

有关如何使用设计实现此功能的任何提示?

感谢。

5 个答案:

答案 0 :(得分:28)

我认为你应该使用类似的东西

authenticated :user do
  root :to => 'users#index', as: :authenticated_root
end
root :to => 'welcome#index'

由于rails4不允许具有相同名称的路由需要指定为:

答案 1 :(得分:24)

This post解释如何实现这一点:

authenticated :user do
  root :to => "main#dashboard"
end

root :to => "main#index"

以下是使用一些技术细节实现此目的的pull request

答案 2 :(得分:6)

authenticated :user do
  root :to => 'home#index', :as => :authenticated_root
end
root :to => redirect('/users/sign_in')

How to's for the devise gem处直接从马的嘴里出来。 :d

答案 3 :(得分:1)

另外,由于您需要在Rails 4中命名这些根路径,您可能会发现当您想在上使用root_path 将您带回仪表板或主页时会很烦人分别。我刚刚在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

答案 4 :(得分:0)

是的,这个问题对我来说也很令人沮丧。

最终我最终只是在会话#new页面上隐藏了flash消息。根本不是一个很好的解决方案,因为有时你/做/希望该消息出现..

我放弃了一段时间,但我想知道你是否可以使用这个approach,但是在lambda中设置了一些标志,并且你的会话控制器中有一个before_filter,如果它存在则清空flash。有点像...

#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

我不太熟悉路由约束和请求对象的工作方式......但只是一个想法。只有当您尝试访问“/”而不是其他页面时,才会关闭Flash消息..

我希望有人有一个很好的解决方案!