ActiveAdmin Devise Cancancan 和三种用户模型——死循环

ActiveAdmin Devise Cancancan and Three User Models -- infinite loop

我目前运行三个用户模型。员工、客户和供应商。每个都有一个设计模型,我似乎可以确定如何只授权员工访问 activeadmin 页面。我设法让一个模型访问它,但随后另外两个模型进入了重定向循环。关于如何让它发挥作用的任何想法都会很棒。

/app/controllers/application_controller.rd
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  before_filter :configure_permitted_parameters, if: :devise_controller?

  def authenticate_staff_user!
    redirect_to new_staff_session_path unless current_staff
  end

  def access_denied(exception)
    redirect_to root_path, :alert => exception.message
  end

  rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to root_url
  end

  protected

  def  configure_permitted_parameters
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:id, :username, :first_name, :last_name, :email, :password, :password_confirmation, :current_password,
                                                                   addresses_attributes:[:id, :address, :other_address_details, :address_type_id],
                                                                   address_types_attributes:[ :id, :address_type])}

    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:id, :username, :first_name, :last_name, :email, :password, :password_confirmation, :current_password,
                                                            addresses_attributes:[:id, :address, :other_address_details],
                                                            address_types_attributes:[ :id, :address_type])}
  end

end


app/models/staff.rb
class Staff < ActiveRecord::Base

  has_many :addresses, foreign_key: 'staff_id'
  has_many :address_types, :through => :addresses
  accepts_nested_attributes_for :addresses


  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  def is_admin?
    self.email && ENV['ADMIN_EMAILS'].to_s.include?(self.email)
  end


  def admin?
    true
  end

end

app/models/customer.rb
class Customer < ActiveRecord::Base

  has_many :addresses, foreign_key: 'customer_id'
  has_many :address_types, :through => :addresses
  accepts_nested_attributes_for :addresses

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  def admin?
   false
  end

  def customer?
    true
  end

  end

app/models/supplier.rb
class Supplier < ActiveRecord::Base

  has_many :addresses, foreign_key: 'supplier_id'
  has_many :address_types, :through => :addresses

  accepts_nested_attributes_for :addresses

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  def admin?
    false
  end

  def supplier?
    true
  end


end


config/initializers/active_admin.rb
Portion only
 # == User Authentication
  #

   config.authentication_method = :authenticate_staff_user!

  # == User Authorization
  
   config.authorization_adapter = ActiveAdmin::CanCanAdapter

 
  # == Current User
  #
  
   config.current_user_method = :current_staff

  # == Logging Out
  
  config.logout_link_path = :destroy_staff_session_path

 
   config.logout_link_method = :delete

  # == Root
  #
  # Set the action to call for the root path. You can set different
  # roots for each namespace.
  #
  # Default:
  # config.root_to = 'dashboard#index'

app/models/ability.rb

def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
     staff ||= Staff.new # guest user (not logged in)

     customer ||= Customer.new # guest user (not logged in)
     supplier ||= Supplier.new # guest user (not logged in)

       if staff.admin?
         can :manage, :all
         can :read, ActiveAdmin::Page, :name => "Dashboard"
       end

     if customer.customer?

         can :read, [:index],  HomeController
         cannot :read, ActiveAdmin::Page, :name => "Dashboard"
       end

     if supplier.supplier?
       can :read, [:index],  HomeController
       cannot :read, ActiveAdmin::Page, :name => "Dashboard"
     end

    if customer
      can :read, [:index],  HomeController
      cannot :read, ActiveAdmin::Page, :name => "Dashboard"
    end
end

您没有在 ability.rb 任何地方的初始化方法中使用用户对象。

def initialize(user)

  user ||= User.new

  if user.admin?
    can :manage, :all
    can :read, ActiveAdmin::Page, :name => "Dashboard"
  end

  if user.customer?
    can :read, [:index],  HomeController
    cannot :read, ActiveAdmin::Page, :name => "Dashboard"
  end

  if user.supplier?
    can :read, [:index],  HomeController
    cannot :read, ActiveAdmin::Page, :name => "Dashboard"
  end
end