我有一个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
模块中覆盖该实例方法?
答案 0 :(得分:8)
我认为你正在寻找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