【问题标题】:Is "proc" required with conditional before_action/before_filter?条件 before_action/before_filter 是否需要“proc”?
【发布时间】:2014-06-15 14:42:50
【问题描述】:

看,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

【问题讨论】:

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


    【解决方案1】:

    在 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 的索引良好且搜索排名很高。

    【讨论】:

    • 从技术上讲,这些是 ActiveRecord 回调,而不是 ActionController 回调,但我想选项语法是相同的。我不确定我是否比 Proc 更喜欢 eval'd 字符串,但感谢您找到文档。
    • 看起来 ActionController 和 ActiveRecord 使用相同的 ActiveSupport::Callbacks 实现:api.rubyonrails.org/classes/ActiveSupport/Callbacks.html ActionController 做了一些规范化以将 :only 和 :except 选项转换为 ActiveSupport::Callbacks 期望的 :if 和 :unless 选项。
    【解决方案2】:

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

    弃用警告:将字符串传递给 :if 和 :unless 条件选项已被弃用,并且将在 Rails 5.2 中删除而无需替换。

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 知道这很有用,但不能解决我的实际问题,即关于文档的问题。
      • 不会有关于 if 和 unless 的文档,因为人们在方法中使用条件
      • 这太棒了
      【解决方案4】:

      我建议使用稳定的 lambda。如果你想知道,为什么? Please read this

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

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

      【讨论】:

        【解决方案5】:

        添加一个方法来检查before_actionif/unless 条件应该是最好的方法,因为这样您以后可以轻松地适应before_action 条件中的任何其他更改:

        class ThingController < ApplicationController
          before_filter :check_stuff, if: :check_stuff?
        
          def check_stuff
          end
        
          private
        
          def check_stuff?
            Rails.env.production?
          end
        end
        

        【讨论】:

          猜你喜欢
          • 2013-05-07
          • 2023-03-08
          • 2022-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-14
          • 1970-01-01
          • 2011-03-23
          相关资源
          最近更新 更多