2012-07-18 107 views
1

在我的新项目中,我有一个资源赌注,其他用户只有在赌注的所有者或他的朋友时才能阅读。主要问题出现在我想定义索引操作的能力时。在索引操作中,块不会被执行,所以我想这不是一个选项。CanCan,嵌套资源和使用方法

让我们来说明一下。如果我想只有所有者才能够索引的赌注,这将是不够的:

can :read, Bet, :user => { :id => user.id } 

但我需要在可接受的IDS是一个范围,一个用户的所有朋友定义。类似于:

if (bet.user == user) || (bet.user.friends.include? user) 
    can :read, Bet 
end 

但这是不正确的CanCan语法。

我想很多人都遇到过CanCan和嵌套资源的问题,但我仍然没有看到任何答案。

回答

0

刚才我找到了解决方案,但我不太喜欢它。这是关于创建自定义操作并为其定义功能。例如...

在控制器:

def index 
    authorize! :index_bets, @user 
end 

在ability.rb:

can :index_bets, User do |friend| 
    user == friend || user.friends.include?(friend) 
end 

它的工作原理,但我不觉得了不起使用它。没有更优雅的东西吗?

1

在您的投注模型,创建一个方法:

def is_accessible_by? (user) 
    owner = self.user 
    owner == user || owner.friends.include?(user) 
end 

现在ability.rb,设置您的康康舞权限:

can :read, Bet { |bet| bet.is_accessible_by?(user) } 

编辑

正如你指出的,由于索引操作没有对象的实例,所以上面的块不会被执行。

但是,这听起来像你正在尝试做的事情 - 列出用户或他们的朋友拥有的投注 - 不应该使用CanCan或权限处理。我会在我的用户模型创建一个函数:

def bet_listings 
    friend_bets = friends.inject([]){ |bets, friend| bets<<friend.bets; bets } 
    self.bets + friend_bets 
end 
索引中的作用

然后: @bets = user.bet_listings

+0

它不工作。能力块中的条件不用于像索引这样的动作。 – Gawyn 2012-07-18 14:23:58

+0

你是对的,我没有仔细阅读你的问题:( 我会再给你一个建议...... – 2012-07-18 14:43:27