Ruby on rails 带参数的前_滤波器
我有一个方法,它可以做这样的事情:Ruby on rails 带参数的前_滤波器,ruby-on-rails,ruby,ruby-on-rails-3,before-filter,Ruby On Rails,Ruby,Ruby On Rails 3,Before Filter,我有一个方法,它可以做这样的事情: before_filter :authenticate_rights, :only => [:show] def authenticate_rights project = Project.find(params[:id]) redirect_to signin_path unless project.hidden end before_filter { |c| c.authenticate_rights correct_id_here }
before_filter :authenticate_rights, :only => [:show]
def authenticate_rights
project = Project.find(params[:id])
redirect_to signin_path unless project.hidden
end
before_filter { |c| c.authenticate_rights correct_id_here }
def authenticate_rights(project_id)
project = Project.find(project_id)
redirect_to signin_path unless project.hidden
end
我还想在其他一些控制器中使用此方法,因此我将此方法复制到应用程序控制器中包含的帮助器中
问题是,在某些控制器中,项目的id不是:id
符号,而是f.e.:project\u id
(并且存在:id
(对于另一个型号)
您将如何解决此问题?是否有向before_filter操作添加参数的选项(以传递正确的参数)?这应该可以:
project = Project.find(params[:project_id] || params[:id])
如果参数散列中存在,则返回params[:project\u id]
,如果不存在,则返回params[:id]
。我会这样做:
before_filter :authenticate_rights, :only => [:show]
def authenticate_rights
project = Project.find(params[:id])
redirect_to signin_path unless project.hidden
end
before_filter { |c| c.authenticate_rights correct_id_here }
def authenticate_rights(project_id)
project = Project.find(project_id)
redirect_to signin_path unless project.hidden
end
其中
correct\u id\u here
是访问项目
以继续@alex'回答的相关id,如果您想:除了
或:仅
某些方法,以下是语法:
before_filter :only => [:edit, :update, :destroy] do |c| c.authenticate_rights params[:id] end
找到。带有一些语法糖:
before_filter -> { find_campaign params[:id] }, only: [:show, :edit, :update, :destroy]
或者,如果你决定变得更加花哨:
before_filter ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|
由于Rails 4在_action之前引入了_filter之前的同义词,因此它可以写成:
before_action ->(param=params[:id]) { find_campaign param }, only: %i|show edit update destroy|
NB
->
代表lambda
,称为lambda literal,在Ruby 1.9中引入
%i
将创建一个符号数组我发现使用大括号而不是do…end
的块方法是最清晰的选项
before_action(only: [:show]) { authenticate_rights(id) }
before\u action
只是before\u filter
较新的首选语法问题是,有时两者都存在(嵌套)它会发现一个项目不是正确的。@choise:这不应该发生:如果存在project\u id
,则或子句将确保使用该项目-只有在未提供project\u id
的情况下,才会选择id
参数。换句话说,当提供了这两个参数时,或子句将被删除URE使用正确的值,因为它总是喜欢project\u id
。当然,当两者都不存在时,或者当没有project\u id
但有一个id
不引用项目时,您不希望调用此方法。是否有方法添加,:only=>[:show]
symbol?我在尝试before\u filter{c | c.authenticate\u rights correct\u id\u here},:only=>[:show]
尝试另一种方法:before\u filter(:only=>[:show]){
这里有更多示例:如果您通过将before\u filter
作为私有方法来确保这一点,那么可能需要重新考虑(例如,将其移动到父控制器、应用程序控制器等),您需要使用c.send(:filter\u name,…)
,因为过滤器不会在控制器上下文中运行。这样做会使before\u过滤器无法因缺少名称而被覆盖/跳过(proc)。我要传递的值是类级别的。这可能吗?@oreoshake:我也有同样的问题。你找到解决方案了吗?这个答案更优雅,因为lambda默认为类的执行上下文,因此可以调用私有方法,而无需使用“.send”@Vadym Tyemirov Isfind\u campaign
私有方法名称?在param=params[:id]
中,param
是将作为参数传递给find_活动
的新局部变量的名称吗?这意味着在find_活动
私有方法本身中,我们使用param
而不是params{:id]
?find_-campaign
也可以,但我会将它设置为私有,以确保我们不会公开未使用的内容。params
是我们的方法可用的散列变量,param
是查找_-campaign方法需要传递的任何变量,例如在_-action之前->(campaign_-id=params[:id{])find_-campaign(活动id)},仅:%i |显示编辑更新销毁|