我将Rails 4与Devise和CanCanCan一起使用,并且由于某种原因,当我试图只给用户CRUD权限时,他们生产的产品没有经过任何CanCanCan权限设置,用户只能进行只读操作。但是,版主权限和管理权限按预期工作。
ability.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
enduser.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 | |
+-----------------------------------+--------------+------+-----+---------+----------------+,这是我的文件结构

发布于 2015-09-15 22:06:21
而不是像这样设置一个块:
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之后定义CRUD操作和/或自定义方法的条件是多余的。
最后,您可能需要尝试在标准访问级别使用不同的符号,因为当您实际上是指用户角色时,符号:user很容易被误认为是用户对象。
发布于 2016-09-11 21:58:05
您似乎在能力类中使用实例变量。试试这个,看看它是否有效:
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
endhttps://stackoverflow.com/questions/32595155
复制相似问题