0

我正在使用带有 Devise 和 CanCanCan 的 Rails 4,并且由于某种原因,当我尝试只为他们制作的产品授予用户 CRUD 权限时,CanCanCan 权限设置都没有通过,用户只能做read only。但是,版主和管理员权限按预期工作。

能力.rb

class Ability
  include CanCan::Ability

     def initialize(user)

       user ||= User.new

    if user.is? :admin
        can :manage, :all
      elsif user.is? :moderator
        can :read, :all
        can :manage, @products
      elsif user.is? :user
        can :read, :all
        can :create, :all
        can :manage, @products do |product|
          product.try(:user) == user
        end
      else
        can :read, :all
      end
    end
  end

用户.rb

  has_many :products
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  before_save :assign_role

  Roles = [ :admin , :moderator , :user ]

  def is?( requested_role )
    self.role == requested_role.to_s
  end

  def assign_role
    self.role = Role.find_by role: "user" if self.role.nil?
  end

.html 文件

  <% if can? :update, @products %>
  <%= link_to "Edit", edit_product_path(@product) %>
  <% end %>
  <% if can? :destroy, @products %>
  <%= link_to "Delete", product_path(@product), method: :delete, data: { confirm: "Are you sure?"} %>
  <% end %>

控制器

class ProductsController < ApplicationController
    respond_to :html, :json
    load_and_authorize_resource
    def create
        @product = current_user.products.build(product_params)
        @product.user_id = current_user.id
        if @product.save
            redirect_to products_path
        else
            render 'new'
        end
    end
        def product_params
            params.require(:product).permit(:product_name, :product_description, :user_id)
        end

编辑:

用户 SQL 表

+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| id                     | int(11)      | NO   | PRI | NULL    | auto_increment |
| created_at             | datetime     | YES  |     | NULL    |                |
| updated_at             | datetime     | YES  |     | NULL    |                |
| email                  | varchar(255) | NO   | UNI |         |                |
| encrypted_password     | varchar(255) | NO   |     |         |                |
| reset_password_token   | varchar(255) | YES  | UNI | NULL    |                |
| reset_password_sent_at | datetime     | YES  |     | NULL    |                |
| remember_created_at    | datetime     | YES  |     | NULL    |                |
| sign_in_count          | int(11)      | NO   |     | 0       |                |
| current_sign_in_at     | datetime     | YES  |     | NULL    |                |
| last_sign_in_at        | datetime     | YES  |     | NULL    |                |
| current_sign_in_ip     | varchar(255) | YES  |     | NULL    |                |
| last_sign_in_ip        | varchar(255) | YES  |     | NULL    |                |
| role                   | varchar(255) | YES  |     | NULL    |                |
+------------------------+--------------+------+-----+---------+----------------+

产品SQL表

+-----------------------------------+--------------+------+-----+---------+----------------+
| Field                             | Type         | Null | Key | Default | Extra          |
+-----------------------------------+--------------+------+-----+---------+----------------+
| id                                | int(11)      | NO   | PRI | NULL    | auto_increment |
| project_goal                      | int(11)      | YES  |     | NULL    |                |
| product_name                      | varchar(255) | YES  |     | NULL    |                |
| product_description               | varchar(255) | YES  |     | NULL    |                |
| project_category                  | varchar(255) | YES  |     | NULL    |                |
...
| expiration_date                   | datetime     | YES  |     | NULL    |                |
| created_at                        | datetime     | YES  |     | NULL    |                |
| updated_at                        | datetime     | YES  |     | NULL    |                |
| user_id                           | int(11)      | YES  |     | NULL    |                |
+-----------------------------------+--------------+------+-----+---------+----------------+

这是我的文件结构

文件结构

4

2 回答 2

1

而不是像这样设置一个块:

can :manage, @products do |product|
  product.try(:user) == user
end

您可以尝试根据 user_id 建立权限:

can :manage, Product do |product|
  product.user_id == user.id
end

您可以更简洁地表达此权限,如下所示:

can :manage, Product, user_id: user.id

虽然上述语法应该可以工作,但如果您遇到问题,请尝试这个稍微详细一点的版本:

can :manage, Product, :user_id => user.id

当然,这种方法假定用户和产品(产品属于用户)之间存在关系。

另外,请记住,这:manage意味着“任何操作”,因此在指定:manage.

最后一点,您可能想尝试为您的标准访问级别使用不同的符号,因为当您实际表示用户角色时,符号 :user 很容易被误认为是用户对象。

于 2015-09-15T22:06:21.080 回答
0

您似乎在您的能力类中使用了一个实例变量。试试这个,看看它是否有效:

class Ability
  include CanCan::Ability

 def initialize(user)

   user ||= User.new

if user.is? :admin
    can :manage, :all
  elsif user.is? :moderator
    can :read, :all
    can :manage, Product # use class here not instance variable
  elsif user.is? :user
    can :read, :all
    can :create, :all
    can :manage, Product do |product| # <–-use the class here not instance variable.
      product.try(:user) == user # cancancan code examples general call ids you might wanna consider revisions?
    end
  else
    can :read, :all
  end
end
  end
于 2016-09-11T21:58:05.337 回答