Rails 3 ActiveAdmin. Перенаправить, если не залогинен - PullRequest
1 голос
/ 31 января 2012

У меня есть этот пользовательский контроллер в ActiveAdmin, позволяющий отображать кнопки в соответствии с ролями пользователя. Я делаю это в файле app / admin / invoices.rb

controller do

  load_and_authorize_resource :except => :index
  def scoped_collection
    end_of_association_chain.accessible_by(current_ability)      
  end

  def action_methods
    ['index'] + (current_admin_user.role=="administrator" ? ['edit','update','new','create','destroy', 'show'] : ['show'])
  end
end

Если пользователь не вошел в систему, я получаю эту ошибку ...

NoMethodError in Admin::InvoicesController#index
undefined method `role' for nil:NilClass

Как я могу вместо этого перенаправить на страницу входа admin_root_path? Я также проверил что-то вроде этого ...

def action_methods
  if current_admin_user.nil?
    redirect_to admin_root_path
  elsif current_admin_user.role == "administrator"
    ['index', 'edit','update','new','create','destroy', 'show']
  elsif current_admin_user.role == "customer"
    ['index']
  else
  end
end

и я получаю эту ошибку

AbstractController::ActionNotFound (AbstractController::ActionNotFound):

Класс AdminUser adminuser.rb класса

class AdminUser < ActiveRecord::Base
      devise :database_authenticatable, 
             :recoverable, :rememberable, :trackable, :validatable

      attr_accessible :email, :password, :password_confirmation, :remember_me, 
        :customer_id, :role

      validates :customer_id, :presence => true, :if => :is_customer?

      belongs_to :customer

      after_create { |admin| admin.send_reset_password_instructions }

      def password_required?
        new_record? ? false : super
      end

      def is_customer?
        self.role == 'customer'
      end

      before_create :set_new_user_as_customer
      def set_new_user_as_customer
        self.role = 'customer'
      end

    end

Способность класса Способности. Rb

class Ability
  include CanCan::Ability

  def initialize(user)

    user ||= AdminUser.new    
    if user.role == "administrator"
        can :manage, :all
    elsif user.role == "customer"
      cannot :create, :all
      cannot :update, :all
      cannot :destroy, :all
      can :read, Shipment, :customer_id => user.customer_id
      can :index, Invoice, :customer_id => user.customer_id      
    else
      cannot :manage, :all
    end
  end 
end

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery

  # Override build_footer method in ActiveAdmin::Views::Pages
  require 'active_admin_views_pages_base.rb'

  rescue_from CanCan::AccessDenied do |exception|
    redirect_to admin_custom_dashboards_path, :alert => exception.message
  end

  def after_sign_in_path_for(resource_or_scope)
    admin_custom_dashboards_path
  end

  def current_ability
    @current_ability ||= Ability.new(current_admin_user)
  end
end

/ приложение / администратор / invoices.rb

ActiveAdmin.register Invoice do
  menu :if => proc{ can?(:manage, Invoice) }, :priority => 2

  controller do

    load_and_authorize_resource :except => :index
    def scoped_collection
      end_of_association_chain.accessible_by(current_ability)      
    end

    def action_methods
      ['index'] + (current_admin_user.role=="administrator" ? ['edit','update','new','create','destroy', 'show'] : ['show'])
    end
  end
  ...

Ответы [ 3 ]

0 голосов
/ 08 февраля 2012

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

def get_user
    current_admin_user = session[:current_user]
end
0 голосов
/ 09 февраля 2012

Ожидаемый результат от action_methods - это массив имен действий, поэтому при попытке вернуть перенаправление из этого метода следует ожидать исключения.Вы должны убедиться, что у вас есть вошедший в систему пользователь с фильтром before (например, before_filter :authenticate_user!).

Еще одна вещь, которую я хотел бы проверить (потому что я вообще не использовал ActiveAdmin или абстрактные контроллеры), это сделатьубедитесь, что ваш AbstractController (controller do ... end) имеет доступ к методам контроллера Devise - в противном случае load_and_authorize_resource, authenticate_user! и т. д. не удастся.

0 голосов
/ 31 января 2012

current_admin_user является объектом класса ruby.

Можете ли вы опубликовать содержимое этого класса (которое содержит метод role?

Я думаю, этот объект не являетсяправильно инициализирован.

Вы делаете ошибку с проверкой if-else. Проверьте это еще раз внимательно.

...