2012-05-30 81 views
0

在我的应用程序中使用CanCan我有权限,用户可以查看和创建商店,但我也希望他们只能编辑他们创建的商店。用户可以根据自己的喜好创建任意数量的商店,这些应该都可以由他们编辑。一家商店没有用户,所以我怎么能做到这一点,当他们没有user_id除了Store表?如何让用户编辑资源不属于用户时创建的资源,但不编辑他人资源?

惨惨:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new 
    if user.role == "default" 
     can :read, Store 
     can :create, Store 
    end 
    end 
end 

回答

3

因为用户将能够创建尽可能多的商店,因为他们喜欢,商店将属于用户。

你必须创建这种关系。

因此,在User模型。

class User < ActiveRecord::Base 
    has_many :stores 
end 

而在Store模型。

class Store < ActiveRecord::Base 
    belongs_to :user 
end 

而在ability.rb文件,只是把像:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new # guest user (not logged in) 
    if user.role == 'default' 
     can :manage, Store , :user_id => user.id 
    end 
    end 
end 
+0

覆盖模型中的'initialize'方法令人不悦。正确的方法是使用'after_initialize'回调。这是因为ActiveRecord并不总是调用'initialize'。 –

1

我将添加以下到店型号:

has_one :created_by, :class => User 

然后添加一个迁移到created_by_id添加到您的存储类。

然后,您应该能够添加一个惨惨::能力:

can :edit, Store, :created_by => user 
+0

如果许多商店可以由'User'创建,我应该使用'has_one'吗? – LearningRoR

+0

是的,每个商店只有一个created_by用户权限?如果你想能够抓住用户的商店,那么你应该把“belongs_to:created_by,:class => User”。然后你可以做User.find(...)。stores或Store.find(...)。created_by。 –

1

我与以前的海报同意,你必须设置UserStore之间的关系。如果商店可以有多个用户,那么这种关系可以是一对多的(如Kleber S.所示),也可以是多对多关系。

然后,通过使用关联,处理访问控制的最佳方式是在控制器中。对于showeditupdatedestroy方法,你需要找到店面,给登录的用户,所以做这样的事情:

class StoresController < ApplicationController 
    before_filter :find_store, only: [:show, :edit, :update, :destroy] 

    def show 
    end 

    def edit 
    end 

    def update 
    if @store.update_attributes(params[:store]) 
     # redirect to show 
    else 
     # re-render edit, now with errors 
    end 
    end 

    # ... 

    private 

    def find_store 
    @store = current_user.stores.find(params[:id]) 
    end 
end 

这样一来,该协会采取限制查找的护理只有那些通过外键连接到current_user的商店。这是RESTful Rails资源执行关联资源访问控制的标准方式。