首页 > 解决方案 > 类中的 before_action 是否覆盖关注中定义的操作?

问题描述

在 Rails 控制器中使用关注点时,通过 before_action 添加的过滤器如何操作?具体来说,如果我有以下代码,FeedsController 中的哪些操作将运行 before_action set_record?全部一次(显示,更新,销毁,foobar),全部一次又两次在销毁之前或仅在销毁之前,foobar(我认为身份验证仍然只在销毁之前运行)?

module JsonApiController
  extend ActiveSupport::Concern

  included do
    before_action :authenticate, only %i[ destroy ]
    before_action :set_record, only: %i[ show update destroy ]
  end

 def show/update/destroy  
 end

 protected

 def set_record
  @record = controller_path.classify.constantize.find(params[:id])
 end

end

class FeedsController < ApplicationController
  include JsonApiController

  before_action :set_record, only: %i[destroy, foobar]

  def foobar
   ...
  end

end

我希望 FeedsController 能够在它想要的任何操作之前添加 set_record 过滤器,而不必知道 JsonApiController 做了什么。因此,理想情况下,过滤器 :set_record 将在每个 show/update/destroy/foobar 之前执行一次,但我认为这不是下面的代码完成的。但比起任何特定的解决方案,我更想知道 before_action 如何处理关注点并包含在内,因此我最大限度地减少了关注点和类之间的代码重复。

如果这只是继承,那么我知道 before_actions 是继承的。但是这个讨论表明,模块中包含的 do 中的 before_action 将被类中的一个覆盖,但是当我尝试查看源代码时,它表明 append_callback 是默认操作,所以我很困惑。

标签: ruby-on-railsrubymetaprogrammingactivesupport-concern

解决方案


来自Rails 指南:动作控制器概述/过滤器

使用不同的选项多次调用同一个过滤器将不起作用,因为最后一个过滤器定义将覆盖以前的过滤器定义。

也就是说,如果您想更改或更新 a 的配置,before_action那么新配置将覆盖所有具有相同方法名称的现有过滤器。

因此,在您的示例中,您将需要使用以下新声明来扩展(实际上覆盖)包含模块的现有声明:

before_action :set_record, only: %i[show update destroy foobar]

推荐阅读