Rails的康康舞和状态机 - 授权状态(Rails cancan and State Machin

2019-07-05 19:09发布

我一直在使用这两个真棒宝石,state_machine和康康舞最近在我的Rails应用程序,但我很好奇,他们干净利落地整合的最佳途径。 目前,我已经放置在参加由控制器授权操作的按钮状态转换。 这完美的作品,我可以限制谁可以执行该操作。

我想给用户更改编辑表单对象的状态以及能力。 我注意到,state_machine将拿起的哈希state_event键,与动作的值,从而进行(所以它会经过所有state_machines回调)。 这可以用在update_attributes方法params哈希表传递英寸 太棒了。

但是只有特定的用户应该能够改变对象的某些状态。 我将如何实现这个? 这个想法是,

params['state_event']=='move_to_x'

要摆脱困境,对于一些用户,但不允许他人。 它还涉及我,直到我实现这个授权部分聪明的用户可以发布状态事件中做任何事,即使他们不应该被允许呢!

Answer 1:

你可以通过两种方式做到这一点。 要么是把一个条件上的转变。 事情是这样的:

 transition :from => :parked, :to => :idling, :if => :valid_user

并建立模型中的valid_user方法。

def valid_user
  if User.current_user.has_role?(xyz)
    do baa
  end
end

(?User.current_user.has_role(XYZ))是不是一个有效的测试 - 你需要自己。

或者你也可以使用自定义的状态机验证:

 state :first_gear, :second_gear do
   validate :speed_is_legal

有一个在文档中发现这个一个警告:

http://rdoc.info/github/pluginaweek/state_machine/master/StateMachine/Integrations/ActiveModel

这里有另一个有趣的帖子:

状态机模型验证和RSpec

我们在我们的应用程序成功地使用这两种方法。

- 编辑,大众 -

关于有关在模型中使用CURRENT_USER注释思考。 我们想了重新阅读我们的代码。 在我们使用这个一个两个例子,我们意识到,我们可以彻底去除CURRENT_USER方法,从而消除任何安全隐患。

与其说User.current_user,我们交换到:

 self.users.first 

这显然假定模型的has_many用户。 然后,您可以拨打该用户的能力



Answer 2:

这实际上并没有那么可怕,因为我以为,我已经在不断的代码,而短期和CURRENT_USER我的模型(所以大加)的方式做到了。

诀窍是调用控制器重新授权。

基本上

def update
  authorize! params[:object][:state_event].to_sym, @object unless params[:object][:state_event].empty?
  .... etc
end

这样,我就可以别名Ability.rb。 因此,用户可以做的动作将被授权,并且用户不能将得到异常。 这也是真棒,因为它是我将使用的基础按钮的动作相同的能力。

唯一需要注意的是,你不能使用@ object.state_transistions获得可用状态,用户可以过渡到一个列表,但它应该有可能通过某种helper方法来做到这一点。

更新:虽然像层视图得到这些国家是很容易

我使用的简单的形式,所以我只是一个集合的输入,使得

 ..... collection: @object.status_transistions.select{|t| can? t.event, @object}

这让选择与所有transistions对象可以顺利通过,并且用户还有权做:)。



文章来源: Rails cancan and State Machine - Authorizing states