ActiveSupport :: Concern模块中的重写方法,这些方法由同一模块中的类方法定义 [英] Overriding methods in an ActiveSupport::Concern module which are defined by a class method in the same module
问题描述
我有一个ActiveSupport :: Concern模块,其外观大致如下:
I have an ActiveSupport::Concern module which looks roughly like the following:
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
.基本上,我用自己的一些额外的自定义逻辑覆盖了ActiveRecord::Enum.enum
创建的declined!
和accepted!
方法.
This is only ever going to be included into ActiveRecord classes, hence the use of enum
. Basically, I'm overriding the declined!
and accepted!
methods that are created by ActiveRecord::Enum.enum
with some extra, custom logic of my own.
问题是,这不起作用,因为当我调用@model.declined!
时,它只是调用declined!
的原始实现,而忽略了我的自定义方法.
The problem is, this doesn't work, because when I call @model.declined!
it justs call the original implementation of declined!
and ignores my custom method.
好像我的自定义方法已被包含在调用类之前中,正在运行所包含的块-意味着我的自定义方法被enum
定义的方法覆盖,而不是其他
Looks like my custom methods are being included into the calling class before the included block is being run - meaning my custom methods are being overridden by the ones defined by enum
, instead of the other way around.
在这种特殊情况下有一些简单的解决方法(例如,我可以将调用enum
移回包含类,并确保它在include MyModel::Acceptance
行上方,但是我想知道是否有办法解决这个问题问题,同时将它们全部保留在同一模块中.
There some easy workarounds in this particular situation (e.g. I could move the call enum
back into the including class and make sure it's above the line include MyModel::Acceptance
, but I'm wondering if there's a way I can solve this problem while keeping it all in the same module.
有什么方法可以在included
中调用定义实例方法的类方法,然后从同一Concern
模块中覆盖该实例方法?
Is there any way I can call a class method within included
that defines an instance method, then override that instance method from within the same Concern
module?
推荐答案
我认为您正在寻找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
这篇关于ActiveSupport :: Concern模块中的重写方法,这些方法由同一模块中的类方法定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!