在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是默认操作,所以我很困惑。
2条答案
按热度按时间zaq34kh61#
从Rails指南:动作控制器概述/过滤器:
使用不同的选项多次调用同一个筛选器将不起作用,因为最后一个筛选器定义将覆盖前面的筛选器定义。
也就是说,如果你想更改或更新
before_action
的配置,那么新的配置将覆盖所有具有相同方法名称的现有过滤器。因此,在您的示例中,您将需要使用以下新声明来扩展(实际上覆盖)包含模块的现有声明:
lpwwtiir2#
正如在其他答案中所讨论的,Rails只会对任何给定方法荣誉
before_action
的最后一次调用。如果您仍然希望将操作保留在关注点中,则可以通过指定一个块来解决。示例: