【问题标题】:Rails controller skip after_actionRails 控制器跳过 after_action
【发布时间】:2017-11-28 06:34:17
【问题描述】:

假设我有一个控制器如下:

class ExampleController < ApplicationController

  after_action -> { puts 'Call me only on success' }

  def create
    obj = Obj.create(obj_params)
    if obj.errors.empty?
      render json: obj
    else
      render json: { errors: obj.errors }, status: 422
    end
  end
end

有没有一种干净的方法来阻止 all after_actions 执行? 我知道的事情:

  1. 设置某种实例变量并在每个after_action 中检查它
  2. render :something and return 不会停止 after_actions
  3. 引发错误(如create!)会起作用,但当我不想返回错误细节并仍以422 响应时,我会使用它

我会接受render :foo and do_not_call_afters之类的东西

【问题讨论】:

  • 只需将代码放在obj.errors.empty? 之后和render json: obj 之前。为什么要输入after_action
  • after_action 方法用于多个动作和控制器,并且可以有很多。我已经更新了问题以反映这一点。
  • 然后您可以创建一个私有方法并为每个操作调用黑色成功代码。你到底想达到什么目的?
  • 不同的控制器定义了不同的after_actions,我正在寻找一种方法来停止所有这些。诸如“立即渲染,不关心之后发生什么”之类的东西

标签: ruby-on-rails ruby


【解决方案1】:

如果成功了可以询问响应:

after_action :call_me_on_success, if: -> { response.successful? }

这适用于所有 2XX 代码:

response.method(:successful?).source
=> "def successful; status >= 200 && status < 300; end"

【讨论】:

  • 这是最好的答案,它仍然需要在每个 after_action 中添加 if 子句,但仅此而已。
【解决方案2】:

一种检查实例变量的方法:

after_action -> { puts 'Call me only on success' } , if: -> { @foo }

根据您的情况在创建方法中设置它。

【讨论】:

  • 我正在寻找更“全局”的解决方案,因此我不必在每个 after_action 中指定 if 子句并在每个操作中设置变量。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多