Rails 和 before_action 具有不同的条件
Rails and before_action with different conditionals
我在控制器中设置了这些 before_action
:
before_action :require_user, unless: :public?, only: [:show]
before_action :require_user, only: [:index, :edit, :update]
基本上,只有当 public?
为 false 时,我才会尝试在 show
操作中执行过滤器 required_front_user
。
对于其余的操作,我希望始终执行过滤器。
看起来第一个 before_action
设置被第二个设置忽略并完全覆盖。
是否可以使用 before_action
语句将两种组合结合起来,还是我必须在过滤器中自行实现此逻辑?
更新
这也行不通:
before_action :require_user, if: :public?, only: [:index, :edit, :update]
before_action :require_user, unless: :public?, only: [:show, :index, :edit, :update]
我以为如果public?
returns true
会加载第一个设置,如果false
会加载第二个设置。碰巧只有第二个设置被加载,如果 public? == true
永远不会触发 before_action
更新 2
这是我发现它有效的方法:
before_action :require_user_when_public, if: :public?, only: [:index, :edit, :update]
before_action :require_user_when_no_public, unless: :public?, only: [:show, :index, :edit, :update]
protected
def require_user_when_public
require_user
end
def require_user_when_no_public
require_user
end
非常难看:/
before_action :require_user, only: require_user_before_actions
private
def require_user_before_actions
actions = [:index, :edit, :update]
actions << :show unless public?
actions
end
我只测试了一点点所以不太确定它会起作用,但可能是这样的:
before_action :require_user, if: ->(c) {
[:index, :edit, :update, !public? && :show].include?(c.action_name.to_sym)
}
作为一个可能愚蠢/损坏的(据我所知,这似乎对我来说在基本测试中有效)替代方案,可能是这样的:
class <<self
alias_method :old_before_action, :before_action
end
def self.before_action(*callbacks)
options = callbacks.extract_options!
if options[:only] && options[:only].is_a?(Proc)
only_proc = options.delete(:only)
if_proc = ->(c) { Array(only_proc.(c)).reject(&:blank?).map(&:to_s).to_set.include? c.action_name }
options[:if] = Array(options[:if]).unshift(if_proc)
end
old_before_action(*callbacks, options)
end
before_action :require_user, only: ->(c) { [:index, :edit, :update, !public? && :show] }
我找到的最干净的方法是:
before_action :require_user, only: [:index, :edit, :update]
before_action :require_user_when_no_public, unless: :public?, only: [:show]
protected
def require_user_when_no_public
require_user
end
我在控制器中设置了这些 before_action
:
before_action :require_user, unless: :public?, only: [:show]
before_action :require_user, only: [:index, :edit, :update]
基本上,只有当 public?
为 false 时,我才会尝试在 show
操作中执行过滤器 required_front_user
。
对于其余的操作,我希望始终执行过滤器。
看起来第一个 before_action
设置被第二个设置忽略并完全覆盖。
是否可以使用 before_action
语句将两种组合结合起来,还是我必须在过滤器中自行实现此逻辑?
更新
这也行不通:
before_action :require_user, if: :public?, only: [:index, :edit, :update]
before_action :require_user, unless: :public?, only: [:show, :index, :edit, :update]
我以为如果public?
returns true
会加载第一个设置,如果false
会加载第二个设置。碰巧只有第二个设置被加载,如果 public? == true
永远不会触发 before_action
更新 2
这是我发现它有效的方法:
before_action :require_user_when_public, if: :public?, only: [:index, :edit, :update]
before_action :require_user_when_no_public, unless: :public?, only: [:show, :index, :edit, :update]
protected
def require_user_when_public
require_user
end
def require_user_when_no_public
require_user
end
非常难看:/
before_action :require_user, only: require_user_before_actions
private
def require_user_before_actions
actions = [:index, :edit, :update]
actions << :show unless public?
actions
end
我只测试了一点点所以不太确定它会起作用,但可能是这样的:
before_action :require_user, if: ->(c) {
[:index, :edit, :update, !public? && :show].include?(c.action_name.to_sym)
}
作为一个可能愚蠢/损坏的(据我所知,这似乎对我来说在基本测试中有效)替代方案,可能是这样的:
class <<self
alias_method :old_before_action, :before_action
end
def self.before_action(*callbacks)
options = callbacks.extract_options!
if options[:only] && options[:only].is_a?(Proc)
only_proc = options.delete(:only)
if_proc = ->(c) { Array(only_proc.(c)).reject(&:blank?).map(&:to_s).to_set.include? c.action_name }
options[:if] = Array(options[:if]).unshift(if_proc)
end
old_before_action(*callbacks, options)
end
before_action :require_user, only: ->(c) { [:index, :edit, :update, !public? && :show] }
我找到的最干净的方法是:
before_action :require_user, only: [:index, :edit, :update]
before_action :require_user_when_no_public, unless: :public?, only: [:show]
protected
def require_user_when_no_public
require_user
end