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

Rails: using before_actions as 'or' conditions

在这种情况下,用户可以满足四个不重叠的条件:A、B、C、and/or D。

鉴于这些条件,是否有比下面的代码更简单、更有效或更 Rails-y 的方法来为 UsersController 编写 before_actions?

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

根据 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