CanCanCan:授权/取消授权特定模型属性

时间:2015-07-28 13:58:25

标签: ruby-on-rails authentication devise rails-admin cancancan

我一直在摆弄CanCanCan gem以限制常规用户的操作,但到目前为止我只设法将授权限制为整个模型,而我真正需要的是限制对其某些属性的访问。

例如,在我的用户模型上,除了用户/密码/电子邮件之外,我有一个用于管理员的布尔值,我用它来验证登录用户的状态,在这种情况下,如果是user.admin ?,它可以访问/管理所有内容,否则,它应该能够读取所有内容,并且只有在user.id匹配时才能更新自己的记录。

我已经多次阅读文档,我最接近的是将其添加到app / models / ability.rb

can :update, :users, [:name, :password, :email]

没有做任何事情。

所以,

问题:用户可以:更新整个模型,或者只是:读取它,我无法将其设置为:update或:读取特定属性。

我需要的是什么:用户能够:仅编辑特定属性。

问题:限制属性的正确语法是什么?我必须在其他一些文件上设置其他任何配置吗?

My Ability.rb文件:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.admin?
      can :manage, :all
      can :import, [User, Enclosure, Blade, Component]
    else
      can :access, :rails_admin
      can :dashboard
      can :read, :all
      can :history, :all
      # Allows user to only edit an enclosure, if it's allocated to itself, or not allocated at all
      can :update, Enclosure do |enclosure|
        can :update, Enclosure if (enclosure.allocated_to == user.email && enclosure.allocation == true) || enclosure.allocation == false
      end 
    end    
  end
end

我使用的宝石(除了默认的Rails 4宝石):

# Administration Panel Gems
gem 'rails_admin'                    # Rails Administration Panel Gem
gem 'rails_admin_history_rollback'   # Enables users to visualize and revert history
gem 'rails_admin_import', "~> 1.0.0" # Enables importing
gem 'devise'                         # Authentication Gem
gem 'cancancan'                      # Authorization Gem
gem 'paper_trail', '~> 4.0.0.rc'     # Auditing Gem (History)

谢谢!

1 个答案:

答案 0 :(得分:5)

我认为你应该使用strong parameters。此gem允许您选择要更新的参数。如果您使用的是Rails 4,则已安装gem,否则为you can install it

class UsersController < ApplicationController
  load_and_authorize_resource

  def update
    if @user.update_attributes(update_params)
      # hurray
    else
      render :edit
    end
  end

  private

  def update_params
    if current_user.admin?
      params.require(:user).permit(:user, :email, :password, :admin)
    else
      params.require(:user).permit(:user, :email, :password)
    end
  end
end