我是Ruby-on-Rails的新手。环顾这个网站和Cancan Guides之后,我可以使用一些帮助。我无法让这个为Cancan和Devise工作。用户(设计)只有价格,因此价格属于用户。
我的数据库中有一个user_id用于我的价格迁移:
create_table "prices", :force => true do |t|
t.string "price_name"
t.decimal "price"
t.date "date"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id"
end
我的价格控制器(一切都是脚手架,但user_id与另一个迁移到价格表中分开):
class PricesController < ApplicationController
before_filter :authenticate_user!
# GET /prices
# GET /prices.xml
def index
@prices = Price.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @prices }
end
end
# GET /prices/1
# GET /prices/1.xml
def show
@price = Price.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @price }
end
end
# GET /prices/new
# GET /prices/new.xml
def new
@price = Price.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @price }
end
end
# GET /prices/1/edit
def edit
@price = Price.find(params[:id])
end
# POST /prices
# POST /prices.xml
def create
@price = current_user.prices.build(params[:price])
respond_to do |format|
if @price.save
format.html { redirect_to(@price, :notice => 'Price was successfully created.') }
format.xml { render :xml => @price, :status => :created, :location => @price }
else
format.html { render :action => "new" }
format.xml { render :xml => @price.errors, :status => :unprocessable_entity }
end
end
end
# PUT /prices/1
# PUT /prices/1.xml
def update
@price = Price.find(params[:id])
respond_to do |format|
if @price.update_attributes(params[:price])
format.html { redirect_to(@price, :notice => 'Price was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @price.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /prices/1
# DELETE /prices/1.xml
def destroy
@price = Price.find(params[:id])
@price.destroy
respond_to do |format|
format.html { redirect_to(prices_url) }
format.xml { head :ok }
end
end
end
然后这是我的Ability.rb(app / models / ability.rb):
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.admin?
can :manage, :all
cannot :destroy, User, :id => current_user.id
else
can :manage, Price, :user_id => user.id
end
end
end
我的问题是,我如何制作,以便只有当前用户可以编辑或删除他或她自己的价格?我的代码不断让任何登录的用户做任何人的价格。
先谢谢。
更新了有效的代码:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
can :manage, Price, :user_id => user.id
end
end
重要* - 删除(或注释掉)编辑,更新,销毁,创建和新的实例变量(例如@),我想知道为什么我的代码不工作,我删除了以下内容并且它完成了它:
def new
# @price = Price.new
def edit
# @price = Price.find(params[:id])
def create
# @price = Price.new(params[:price]) or @price = current_user.prices.build(params[:price])
def update
# @price = Price.find(params[:id])
def destroy
# @price = Price.find(params[:id])
然后在PriceController的顶部:
class PricesController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
skip_authorize_resource :only => :show
答案 0 :(得分:3)
您已经定义了权限,但您还必须在控制器和可能的视图中检查它们,以便强制执行它们。
index
和show
操作,例如:
def index
# Check if the current user can actually see the Price index.
authorize! :index, Price
@prices = Price.all
# ...
end
def show
@price = Price.find params[:id]
# Check if the current user can actually see the Price.
authorize! :show, @price
# ...
end
如您所见,调用遵循格式authorize! :action, object
,其中object
可以是类本身或其实例。当你有一个可用时,你应该使用后者。
为了简单起见,您只需在控制器中的某处添加此行:
authorize_resource
每次操作都会自动authorize! params[:action], @price || Price
。 @price || Price
惯用语意味着@price
将被使用,除非它是nil
,在这种情况下Price
将被使用。
此外,请记住,如果当前用户没有所需的权限,对authorize!
的调用将引发CanCan::AccessDenied
异常。您应该在ApplicationController
:
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_url, :alert => exception.message
end
查看CanCan Wiki上的Authorizing Controller Actions以获取更多详细信息。
答案 1 :(得分:1)
尝试将一个before_filter放入你的控制器中,并确保用户可以做感兴趣的事情。这可以保护后端。
然后还使用cancan权限隐藏或以其他方式可视地保护前端数据。