ruby 类中的before_action是否覆盖关注点中定义的操作?

mv1qrgav  于 2023-06-29  发布在  Ruby
关注(0)|答案(2)|浏览(142)

在Rails控制器中使用关注点时,通过before_action添加的过滤器如何操作?具体来说,如果我有以下代码,那么before_action set_record将为FeedsController中的哪些操作运行?所有这些都只运行一次(show,update,destroy,foobar),所有这些都在destroy之前运行一次和两次,或者只在destroy之前运行一次,foobar(我假设authenticate仍然只在destroy之前运行)?

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做了什么。因此,理想情况下,filter:set_record会在每次执行show/update/destroy/foobar之前执行一次,但我不认为这是下面的代码所完成的。但是,比起任何特定的解决方案,我更想知道before_action是如何与关注点和包含的一起工作的,所以我最小化了关注点和类之间的代码重复。
如果这只是继承,那么我知道before_actions是继承的。但是this discussion建议模块中包含的do中的before_action将被类中的一个覆盖,但是当我试图查看源代码时,它建议append_callback是默认操作,所以我很困惑。

zaq34kh6

zaq34kh61#

从Rails指南:动作控制器概述/过滤器:
使用不同的选项多次调用同一个筛选器将不起作用,因为最后一个筛选器定义将覆盖前面的筛选器定义。
也就是说,如果你想更改或更新before_action的配置,那么新的配置将覆盖所有具有相同方法名称的现有过滤器。
因此,在您的示例中,您将需要使用以下新声明来扩展(实际上覆盖)包含模块的现有声明:

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

lpwwtiir2#

正如在其他答案中所讨论的,Rails只会对任何给定方法荣誉before_action的最后一次调用。如果您仍然希望将操作保留在关注点中,则可以通过指定一个块来解决。示例:

before_action(only: %i[destroy, foobar]) { set_record }

相关问题