CanCanCan:authorize/unauthorize 个特定模型属性

CanCanCan: authorize/unauthorize specific model attributes

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

例如,在我的用户模型中,除了 user/password/email 之外,我还有一个管理员布尔值,我用它来验证登录用户的状态,在这种情况下,如果 user.admin ?,它可以 access/manage 一切,否则,它应该能够读取所有,并且只能在 user.id 匹配时更新自己的记录。

我已经通读了很多遍文档,最接近的是将它添加到 app/models/ability.rb

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

什么都不做。

所以,

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

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

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

我的 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 gems):

# 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)

谢谢!

我认为你应该使用 strong parameters. This gem lets you choose which parameters do you want to be updated. If you are using Rails 4, the gem is already installed, otherwise 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