覆盖ActiveSupport :: Concern模块中的方法,这些方法由同一模块中的类方法定义

我有一个ActiveSupport :: Concern模块,看起来大致如下:

module MyModel module Acceptance extend ActiveSupport::Concern included do enum status: [:declined, :accepted] end def declined! self.status = :declined # some extra logic self.save! end def accepted! self.status = :accepted # some extra logic self.save! end end end 

这只会被包含在ActiveRecord类中,因此使用enum 。 基本上,我压倒了declined!accepted!ActiveRecord::Enum.enum创建的方法,以及我自己的一些额外的自定义逻辑。

问题是,这不起作用,因为当我调用@model.declined! 它只是调用原来执行的declined! 并忽略我的自定义方法。

看起来我的自定义方法在运行包含块之前被包含到调用类中 – 这意味着我的自定义方法被enum定义的方法覆盖,而不是相反。

在这种特殊情况下有一些简单的解决方法(例如,我可以将调用enum移回包含类并确保它在行上方include MyModel::Acceptance ,但我想知道是否有一种方法可以解决此问题同时保持这一切都在同一个模块中。

有没有什么方法可以调用included在定义实例方法的类方法,然后在同一个Concern模块中覆盖该实例方法?

我想你正在寻找define_method

 module MyModel module Acceptance extend ActiveSupport::Concern included do enum status: [:declined, :accepted] define_method :declined! do self.status = :declined # some extra logic self.save! end define_method :accepted! do self.status = :accepted # some extra logic self.save! end end end end