活动管理员用户新页面出错

时间:2012-06-19 07:34:37

标签: ruby-on-rails-3 activeadmin

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

  1. 超级管理员
  2. 机构管理员
  3. 使用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我可以从机构用户创建新用户但在索引上   页面我可以看到所有用户(而不仅仅是来自的用户)   机构)

1 个答案:

答案 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相同”。