Rails:使用before_actions作为'或'条件

时间:2015-07-08 16:58:33

标签: ruby-on-rails-4 controller

在这种情况下,用户可以满足四种不重叠的条件:A,B,C和/或D.

  • #show之前,除非用户满足条件A,B或C,否则应重定向用户。

  • #edit#update#destroy之前,除非用户满足条件B或C,否则应重定向用户。

  • #index之前,除非用户满足条件C,否则应重定向用户。

鉴于这些条件,是否有更简单,更有效或更多Rails-y方式为before_action编写UsersController而不是下面的代码?

before_action :a_through_c, only: [:show]
before_action :b_through_c, only: [:edit, :update, :destroy]
before_action :c,           only: [:index]
...

private

def a_through_c
  b_through_c unless current_user.satisfies_condition?(a)
end

def b_through_c
  c unless current_user.satisfies_condition?(b)
end

def c
  redirect_to(root_url) unless current_user.satisfies_condition?(c)
end

您知道,我之前没有找到以下代码 - 只有B或C应允许#edit#update#destroy通过,并且仅C应该允许#index通过。下面的代码允许A,B或C传递任何操作。

before_action :accessible, only: [:show, :index, :edit, :update, :destroy]
...
private

def accessible
  unless
    current_user.satisfies_condition?(a) ||
    current_user.satisfies_condition?(b) ||
    current_user.satisfies_condition?(c)
    redirect_to(root_url)
  end
end

1 个答案:

答案 0 :(得分:0)

根据steve klein的评论。我喜欢这个解决方案,因为它的透明度。如果这不是一个假设的例子,我肯定会修改satisfies_condition方法来获取参数数组(对于DRYness)。

before_action :a_or_b_or_c, only: [:show]
before_action :b_or_c, only: [:edit, :update, :destroy]
before_action :c, only: [:index]

...

private

def a_or_b_or_c
  unless
    current_user.satisfies_condition?(a) ||
    current_user.satisfies_condition?(b) ||
    current_user.satisfies_condition?(c)
    redirect_to root_url
  end
end

def b_or_c
  unless
    current_user.satisfies_condition?(b) ||
    current_user.satisfies_condition?(c) ||
    redirect_to root_url
  end
end

def c
  unless
    current_user.satisfies_condition?(c)
    redirect_to root_url
  end
end