我有两种类型的管理员用户
使用cancan进行跟踪。
超级管理员可以创建机构管理员/其他超级管理员以及与该机构相关的普通用户,并可以管理所有其他事项,如兴趣类型,目标等。 此外,超级管理员还可以查看系统中创建的所有用户。
机构管理员可以创建仅与该机构相关的用户,并且只能看到与该机构相关的用户。
所以一切正常,除非有一件事。当我使用机构管理员登录并在页面上创建新用户时,它会向我显示以下错误。
ActiveRecord::HasManyThroughNestedAssociationsAreReadonly in Admin::UsersController#new
Cannot modify association 'AdminUser#users' because it goes through more than one other association.
模型/ admin_user.rb
class AdminUser < ActiveRecord::Base
belongs_to :institution
has_many :profiles, :through => :institution
has_many :users, :through => :profiles
devise :database_authenticatable,
:recoverable, :rememberable, :trackable, :validatable
def password_required?
new_record? ? false : super
end
def all_users
if role == "super_admin"
User.unscoped
else
#may be below line of code has issue.
users
end
end
end
模型/ ability.rb
class Ability
include CanCan::Ability
def initialize(current_admin_user)
# Define abilities for the passed in user here. For example:
current_admin_user ||= AdminUser.new # guest user (not logged in)
case current_admin_user.role
when "super_admin"
can :manage, :all
when "institution_admin"
can :manage, User, :profile => {:institution_id => current_admin_user.institution_id}
can :manage, InterestType, :institution_id => current_admin_user.institution_id
end
end
end
控制器/ users_controller.rb
class UsersController < ApplicationController
layout "home"
skip_before_filter :require_login, :only => [:new, :create, :activate]
def new
@user = User.new
@user.build_profile
end
def create
@user = User.new(params[:user])
if @user.save
redirect_to home_path, :notice => "Please check email."
else
render :new, :alert => @user.errors
end
end
end
管理员/ admin_users.rb
ActiveAdmin.register AdminUser do
menu :if => proc{ can?(:manage, AdminUser) } controller.authorize_resource
index do
column :email
column ("Role") {|admin_user| admin_user.role == "super_admin" ? "Administrator" : "Institution Administrator" }
column ("Instituion") { |admin_user| admin_user.institution.name unless admin_user.institution_id.nil? }
column :current_sign_in_at
column :last_sign_in_at
column :sign_in_count
default_actions end
#... form do |f|
f.inputs "Admin Details" do
f.input :email
f.input :role, :as => :select, :include_blank => false, :collection => Hash[ "Institution Administrator", "institution_admin", "Administrator", "super_admin"]
f.input :institution_id, :as => :select, :include_blank => false, :collection => Institution.all.map{ |ins| [ins.name, ins.id] }
end
f.buttons end
after_create { |admin| admin.send_reset_password_instructions unless admin.email.blank? and admin.institution_id.blank? }
def password_required?
new_record? ? false : super end
end
管理员/ users.rb的
ActiveAdmin.register User do
menu :if => proc{ can?(:manage, User) }
controller.authorize_resource
scope_to :current_admin_user, :association_method => :all_users
index do
column :username
column :email
column ("Instituion") { |user| user.profile.institution.name }
column :activation_state
column("Name" ) {|user| user.profile.users_firstname + " " + user.profile.users_lastname}
column :created_at
end
form do |f|
f.inputs "User Details" do
f.input :username
f.input :email
if f.object.id.nil?
f.input :password
f.input :password_confirmation
end
end
f.inputs "Profile Details", :for => [:profile, f.object.profile || Profile.new] do |profile_form|
profile_form.input :users_firstname
profile_form.input :users_lastname
profile_form.input :users_telephone
profile_form.input :class_year, :collection => 1995..2020, :selected => Time.now.year
if current_admin_user.role == "super_admin"
profile_form.input :institution_id, :as => :select, :include_blank => false, :collection => Institution.all.map{ |ins| [ins.name, ins.id] }
elsif current_admin_user.role == "institution_admin"
profile_form.input :institution_id, :as => :hidden, :value => current_admin_user.institution_id
end
end
f.buttons
end
end
注意:当我将admin_users.rb中的def all_users从用户编辑到 User.scoped我可以从机构用户创建新用户但在索引上 页面我可以看到所有用户(而不仅仅是来自的用户) 机构)
答案 0 :(得分:1)
您可以通过将users
中的all_users
行修改为:
User.joins(:profile => :institution).where(["#{Institution.table_name}.id = ?", institution.id])
这不会在新用户上设置个人资料,因此您仍需要以与分配机构相同的方式在表单中指定该个人资料。您还需要确保Profile和Institution之间存在双向关联。
您收到错误的原因是ActiveRecord不允许您通过关联从嵌套的has_many创建新记录。我们正在通过获得相同关联的结果而不经过has_many来解决这个问题。该查询相当于说“让我所有属于个人资料的用户,而这个用户又是机构的一部分,其中机构的ID与当前用户的机构ID相同”。