1

Использование Rails 4.2.1, ActiveAdmin 1.0.0pre2, CanCanCan 1.13.1с помощью переменных сеанса в канкан с ActiveAdmin

нужно использовать переменные сессии, как часть моего канкан разрешения. Причина, по которой я хочу это (вместо сохранения переменной в базе данных), - это позволить администратору иметь разные роли в нескольких одновременных сеансах.

Согласно this post, это возможно или только с использованием CanCan. Но сам CanCan не имеет доступа к переменным сеанса и поэтому должен быть передан в качестве дополнительного параметра при инициализации способности.

Я пришел к тому, что могу успешно модифицировать адаптер CanCan для передачи дополнительных параметров в метод Ability.new, но я слишком необразован в ruby ​​/ rails, чтобы создать правильный контекст для доступа к переменным сеанса.

Вот что я пробовал:

конфигурации/Инициализаторы/active_admin.rb

#the usual 
config.authorization_adapter = ActiveAdmin::CanCanAdapter 
: 
: 
#at end of file, modify the standard CanCanAdapter class: 
module ActiveAdmin 
    class CanCanAdapter < ActiveAdmin::AuthorizationAdapter 
    def initialize_cancan_ability 
     klass = resource.namespace.cancan_ability_class 
     klass = klass.constantize if klass.is_a? String 
     klass.new user, session 
    end 
    end 
end 

Ключевое изменение (относительно оригинального модуля CanCanAdapter) является строка «klass.new пользователя, сессия [ : admin_role] ", в котором я добавил второй сеанс параметра [: admin_role].

приложение/модели/ability.rb

class Ability 
    include CanCan::Ability 

    def initialize(user, session) 
    user ||= User.new # guest user (not logged in) 
    if user.is_admin? && session[:admin_role]==User.ROLE_ADMINISTERING 
     can :manage, :all 
    end 
    : 
    #other types of authorizations 
    : 
    end 
end 

Хотя этот метод был успешным в принципе пройти вторую переменную для инициализации Ability, он бросает исключение, потому что сессия объект не является доступный для класса CanCanAdapter.

(т. Е. Замените строку class.new user, session [: admin_role], например, на константу literal, и я могу проверить, что константа передается методу Ability).

Итак, возникает вопрос, как я могу получить доступ к сеансу в адаптере CanCan? Согласно this post, это возможно с помощью ActionDispatch :: Request.new (ENV), но я не смог понять обсуждение достаточно, чтобы сделать эту работу.

Там также были сообщения, связанные с модификацией метода ActionController следующим образом:

def current_ability 
    @current_ability ||= Ability.new(current_user, session) #added session parameter 
end 

, но я не смог найти место, чтобы поместить этот код, который сделал разницу.

Любая помощь с моим методом или предложения по другому методу для достижения того же, были бы весьма полезны.

ответ

0

Я не знаю, если это «правильный» способ сделать это, но он работал на меня:

Во-первых, я добавил request_store камень из https://github.com/steveklabnik/request_store

gem 'request_store' 

Во-вторых, я добавлено это в мой application_controller.rb для сохранения данных сеанса.

before_filter :store_session_data 

    def store_session_data 
    RequestStore.store[:session] = session 
    end 

В-третий, я изменил свой пересмотренный адаптер, как, например:

module ActiveAdmin 
    class CanCanAdapter < ActiveAdmin::AuthorizationAdapter 
    def initialize_cancan_ability 
     klass = resource.namespace.cancan_ability_class 
     klass = klass.constantize if klass.is_a? String 
     klass.new user, RequestStore.store[:session] 
    end 
    end 
end 

Надеется, что это помогает.

+0

спасибо, он отлично работает. –