ActiveSupport :: Concern模块中的重写方法,这些方法由同一模块中的类方法定义 [英] Overriding methods in an ActiveSupport::Concern module which are defined by a class method in the same module

查看:167
本文介绍了ActiveSupport :: Concern模块中的重写方法,这些方法由同一模块中的类方法定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆