条件before_action / before_filter需要“proc”吗?

时间:2014-04-29 15:04:09

标签: ruby-on-rails-4 before-filter

看哪,before_filter

class ThingController < ApplicationController
  before_filter :check_stuff, :if => proc {Rails.env.production?}
end

在最近的代码审核期间,我被问到,“这需要proc吗?”答案似乎是'是',但这是一个合理的问题,我打算通过引用Rails文档或指南或使用before_filter的条件(现在是before_action的别名)来回答它。

我找不到任何东西。 Action Controller Guide提及:only / :except,但不是:if / :unless

如果失败了,我可以指出的代码中有哪些内容可以解决这个问题吗?它简要提到here,但更多的是关于如何处理:only:except,而不是:if:unless

5 个答案:

答案 0 :(得分:59)

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

结果总是需要Proc才能正常工作。

  

:if:unless选项,可以使用符号,字符串,ProcArray

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

before_action :check_stuff, if: "Rails.env.production?"

在Rails文档中查找内容有时会很痛苦,但至少这样的问题会使得随着时间的推移更容易找到,因为StackOverflow编制得很好并且搜索排名很高。

答案 1 :(得分:17)

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

  

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

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

class ThingController < ApplicationController
  before_action :check_stuff, :if => proc {Rails.env.production?}
end

答案 2 :(得分:8)

我之前在我的代码上做过这个。我希望这个例子对你有所帮助。如果你可以使用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

答案 3 :(得分:0)

我建议使用staby lambda

class ThingController < ApplicationController
  before_action :check_stuff, if: -> {Rails.env.production?}
end

几乎等同于Upvote Me的答案。

答案 4 :(得分:0)

添加一个方法来检查 if/unlessbefore_action 条件应该是最好的方法,因为这样您可以在将来轻松适应 before_action 条件中的任何其他更改:< /p>

class ThingController < ApplicationController
  before_filter :check_stuff, if: :check_stuff?

  def check_stuff
  end

  private

  def check_stuff?
    Rails.env.production?
  end
end