2

我有两种类型的管理员用户

  1. 超级管理员
  2. 机构管理员

使用 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

模型/能力.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

管理员/用户.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 从 users 编辑到 User.scoped 时,我可以从机构用户创建新用户,但在索引页面上我可以看到所有用户(而不仅仅是来自机构的用户)

4

1 回答 1

1

users您可以通过将行修改为来修复错误all_users

User.joins(:profile => :institution).where(["#{Institution.table_name}.id = ?", institution.id])

这不会在新用户上设置配置文件,因此您仍然需要以与分配机构相同的方式分配该配置文件。您还需要确保个人资料和机构之间存在双向关联。

您收到错误的原因是 ActiveRecord 不允许您通过关联从嵌套的 has_many 中创建新记录。我们正在通过获得相同关联的结果来解决这个问题,但没有经过 has_many。该查询相当于说“让我获取属于配置文件一部分的所有用户,该配置文件又是机构的一部分,其中机构的 ID 与当前用户的机构 ID 相同”。

于 2012-07-10T08:05:34.807 回答