条件before_action/before_filter需要"proc"吗?

MrT*_*rus 39 before-filter ruby-on-rails-4

看哪,一个before_filter:

class ThingController < ApplicationController
  before_filter :check_stuff, :if => proc {Rails.env.production?}
end
Run Code Online (Sandbox Code Playgroud)

在最近的一次代码审查中,我被问到:"这proc是否需要这个?" 答案似乎是'是',但这是一个合理的问题,我打算通过引用Rails文档或指南或者使用条件before_filter(现在是别名before_action)来回答它.

我找不到任何东西.该动作控制器指南提到:only/ :except,而不是:if/ :unless.

如果失败了,我可以指出代码中的某个地方是否涵盖了这一点?它简单提到这里,但更多的是如何:only:except被处理,而不是:if:unless.

Den*_*nis 59

在Rails指南上找到它:http://guides.rubyonrails.org/active_record_callbacks.html#conditional-callbacks

结果Proc并不总是需要它才能工作.

:if:unless选项,这可能需要一个符号,一个字符串,一个Proc或一个Array.

所以在你的情况下你可能会逃脱

before_action :check_stuff, if: "Rails.env.production?"
Run Code Online (Sandbox Code Playgroud)

在Rails文档中查找内容有时可能很痛苦,但至少这样的问题会使事情随着时间的推移更容易找到,因为StackOverflow已被很好地编入索引并具有很高的搜索排名.

  • 看起来ActionController和ActiveRecord使用相同的`ActiveSupport :: Callbacks`实现:http://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html ActionController执行一些规范化转换:only和:除了选项:if和:除非选项ActiveSupport :: Callbacks期望. (4认同)
  • 从技术上讲,那些是ActiveRecord回调,而不是ActionController,但我想选项语法是一样的.我不确定我是否比Proc更喜欢eval'd字符串,但感谢您找到文档. (2认同)

Ami*_*ani 20

从Rails 5.2开始,当前接受的答案不再有效,并且将字符串传递给条件将失败.

弃用警告:将字符串传递给:if和:除非条件选项已弃用,并且将在Rails 5.2中删除而不进行替换.

展望未来,proc现在是在原始问题中添加条件的最佳方式:

class ThingController < ApplicationController
  before_action :check_stuff, :if => proc {Rails.env.production?}
end
Run Code Online (Sandbox Code Playgroud)


jim*_*gic 9

我刚刚在我的代码上完成了这个.我希望这个例子对你有所帮助.如果你可以使用if语句但是应该指向另一种方法,就像我在这里做的那样.

class Admin::ArticlesController < ApplicationController
  before_filter :deny_access, :unless => :draft_and_admin?

  def show
    @article = Article.find(params[:id])
  end

  protected

  def draft_and_admin?
    Article.find(params[:id]).draft? && current_user.admin?
  end
end
Run Code Online (Sandbox Code Playgroud)


Imr*_*mad 6

我建议使用稳定的 lambda。如果你想知道,为什么? 请阅读这个

class ThingController < ApplicationController
  before_action :check_stuff, if: -> { Rails.env.production? }
end
Run Code Online (Sandbox Code Playgroud)

这几乎等同于 Upvote Me 的答案。