Rails 3 ActiveAdmin。如果未登录则重定向

时间:2012-01-31 00:23:56

标签: ruby-on-rails ruby activeadmin

我在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

Ability class ability.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

/app/admin/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 :(得分:0)

current_admin_user是ruby类的对象。

您可以发布该类的内容(包含role方法吗?

我认为,此对象未正确初始化。

你在if-else检查时犯了一些错误。仔细检查一遍。

答案 1 :(得分:0)

看起来您需要通过设置当前的admin用户变量来使当前用户对象可用于视图。目前current_admin_user为零,因此显然没有定义。如果您有会话控制器,请在会话控制器中尝试以下内容。

def get_user
    current_admin_user = session[:current_user]
end

答案 2 :(得分:0)

action_methods的预期结果是一系列操作名称,因此当您尝试从该方法返回重定向时,您应该会遇到异常。您应该确保您有一个使用过滤器的登录用户(例如before_filter :authenticate_user!)。

我要检查的另一件事(因为我一般没有使用过ActiveAdmin或抽象控制器)是为了确保你的AbstractController(controller do ... end)可以访问Devise控制器方法 - 否则load_and_authorize_resourceauthenticate_user!等将失败。