Rails 3& cancan:不允许用户编辑记录但能够吗?

时间:2011-04-09 19:30:31

标签: ruby-on-rails cancan

我正在尝试使用cancan实现特定的对象(行)授权,我希望它以一种用户只能对Record进行更改(更新/编辑)的方式工作特定Record的角色。在咨询了康康文档后,我尝试了以下操作:

class Ability
  include CanCan::Ability
  def initialize(user)
     can :manage, Record do |record|
        user.can_edit(record)
     end
  end
end


class User
  has_many :assignments
  has_many :roles_as_editor, :through => :assignments, :class_name => "Role", :source => :role, :conditions => {:edit => true}
  def rec_as_editor
    self.roles_as_editor.collect{ |x| Record.where(:cp_secondary_id => x.record_id) }.flatten.uniq
  end

  def can_edit(rec)
    rec_as_editor.include?(rec)
  end
end

can_edit方法接受Record对象并确保用户具有通过返回true或false来对其进行更改所必需的角色。这个方法经过测试并且工作正常所以问题似乎与CanCan代码有关,因为当我尝试编辑一个记录时,用户有权持有它的角色仍然允许我对记录进行更改,任何人都知道为什么这不起作用?

如果您需要任何进一步的信息,请通过评论告诉我。

谢谢

3 个答案:

答案 0 :(得分:3)

您是在授权控制器中的资源吗?

你的控制器应该有load_and_authorize_resource

def edit
    @critical_process = CriticalProcess.find(params[:id])
    #this here is what you use
    authorize! :edit, @critical_process
  end 

在关键过程控制器内的编辑方法中。

答案 1 :(得分:1)

我个人更喜欢将此逻辑与模型完全分开,这样我就不必深入了解模型代码来查找授权问题。换句话说,user.can_edit检查授权,这是能力文件应该负责的。不管怎么样......在这种情况下我认为你可能在can_edit方法中有问题。我使用的代码看起来几乎和你的代码完全没有问题很多次:

can :manage, Record do |record|
  user.has_role?(:record_manager)
end

我建议包含can_edit的代码或使用调试器查看can_edit返回的值。

答案 2 :(得分:0)

我认为问题来自于您查询应该将用户作为编辑者的记录的方式。

我复制/粘贴您的代码并从头开始构建其他关联。 并在控制台中测试它,当我使用它时它按预期工作:

>> u = User.last
>> a = Ability.new(u)
>> a.can :edit, Role.last
false

我唯一改变的是对记录的查询:它似乎寻找拥有该角色的记录(您的角色有 record_id ),但随后在cp_secondary_id下查找相同的密钥。

我认为您的查询有问题,但取决于您的架构和关联:

roles_as_editor.collect{ |x| Record.where(:cp_secondary_id => x.record_id) }.flatten.uniq

因为我理解你的代码,我们正在遍历这样的联想:

User=>Assignment<=Role(boolean edit flag)<=Record