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
我目前运行三个用户模型。员工、客户和供应商。每个都有一个设计模型,我似乎可以确定如何只授权员工访问 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