before_action with“or”statement

时间:2016-07-08 12:22:50

标签: ruby-on-rails devise

我的应用程序中有几种不同的用户类型。我在访问控制器时试图做这样的事情;

Traceback (most recent call last):
File "<stdin>", line 3, in <module>
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/scoping.py", line 157, in do
    return getattr(self.registry(), name)(*args, **kwargs)
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/session.py", line 1702, in merge
    object_mapper(instance)  # verify mapped
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/base.py", line 266, in object_mapper
    return object_state(instance).mapper
File "/Users/cuducos/.virtualenvs/alchemydumps/lib/python3.5/site-packages/sqlalchemy/orm/base.py", line 288, in object_state
    raise exc.UnmappedInstanceError(instance)
sqlalchemy.orm.exc.UnmappedInstanceError: Class 'sqlalchemy.util._collections.KeyedTuple' is not mapped

要检查用户类型是否允许访问此控制器。

唉,这似乎不对。 Rails只关注第一个class Admins::ProgrammesController < ApplicationController # only allow entry if the user is one of these types. before_action :authenticate_admin! || :authenticate_super_admin! || :authenticate_programme_leader! || :authenticate_caseworker! def index end 参数 - 检查用户是否为admin。因此,如果用户是个案工作者,我的规范就不会通过。

我怎样才能以类似的方式实现这一目标?

更新

根据要求,更多代码..

这是我失败的规范;

before_action

我100%确信正在创建Casework类型用户。这是工厂;

RSpec.describe Admins::ProgrammesController, :type => :controller do
  context 'authenticated user' do
    before :each do
      @user = FactoryGirl.create :caseworker
      sign_in @user
    end

    describe 'GET index' do
      it 'responds with a 200 OK status code' do
        get :index
        expect(response).to have_http_status(:success)
      end
    end
  end
end

以下是路线文件中的相关行;

FactoryGirl.define do
  factory :caseworker, class: 'Users::Caseworker' do
    email { "me@example.com" }
    password { "password" }
  end
end

2 个答案:

答案 0 :(得分:0)

中定义自定义方法
## application_controller.rb

def authenticate!
  if [ current_admin, current_super_admin, current_programme_leader,current_caseworker ].all? {|e| e.nil?}
    :authenticate_admin! ### We can only redirect to one sign in page if there is no user logged in
  end
end

并在您的控制器中使用此方法

before_action :authenticate!

答案 1 :(得分:0)

这样的东西
authenticate_admin! || authenticate_super_admin! || ... 

不起作用,因为如果(例如)管理员未在authenticate_admin!中登录,则会触发重定向。接下来发生的事情并不重要,重定向仍然会发生。

您可以轻松编写过滤器,例如

def check_authenticated?
  if current_admin || current_super_admin ...
    #let them in
  else
    #redirect them
  end
end

但是还有devise groups的概念允许你做类似

的事情
class Admins::ProgrammesController < ApplicationController
  devise_group :programme_editor, contains: %i(admin super_admin case_worker)
  before_action :authenticate_programme_editor!
end

在这个控制器中,您将获得通常的帮助者:current_programme_editorprogramme_editor_signed_in?按指定的顺序查找/检查任何命名事物的存在。

你也得到current_programme_editors,这是所有用户等,而不仅仅是第一个用户。