新手问题 ruby 获取 model 名字

easyhappy · 2013年07月13日 · 最后由 meeasyhappy 回复于 2013年07月13日 · 3995 次阅读
class A < ActiveRecord::Base
  include C
end

class B < A
end

module C
  def self.include(base)
      #问题 怎么 在这里 获取到 B
  end
end

我的问题是 怎么在 C 的 self.include 中 获取到 B 的名字, 请知道的告诉一下,谢谢!!

module C
  def self.included(base)
    def base.inherited(sub_class)
      p sub_class #=> B
    end
  end
end

class A
  include C
end

class B < A
end

但是你确定要这样做吗?需求是什么?Concern 不能满足吗?

需求是这样的

class A < ActiveRecord::Base
  include C
end

class B < A
end

class D < A
end

class E < A
end

module C
  def self.include(base)
      #需求 是这样 ,判断是 B 还是D、E
      # 如果是B 进行 一定的操作
     # 如果是 D 或者E 进行 一定的操作
  end
end

那不用关心是哪个类,只需要知道"某个特征"就好了,duck typing

#3,这里 特征 就是 获取 base 的 子类的名字..., 通过 子类名字 进行判断。

同时 试了一下 你说的 self.inherited 的方式。只有 B.new 的时候 才会 调用 (不能满足 需求)

需求是 在加载 module C.include 的时候 就判断 子类 是什么。

#2 楼 @meeasyhappy 这是被你抽象过的需求,原始需求是什么呢?也许换种抽象方式就解决了 inherited 不是 new 的时候才触发,定义继承的时候就触发了 你可以试试用 concern,让 A、B、C 都 extend 一个 concern class,不过不知道你的真实需求,只是猜测了

确实 是抽象过的 需求

以前 是这样的:

class A < ActiveRecord::Base
  include C
end


class D < A
end

class E < A
end

module C
  def self.include(base)
     ... 都是一样的
  end
end

现在 需要 新加入一个 class B,然而 B 大部分 都是 D、E 一样 就是一个方法 不一样... 所以 就有 最上面的问题了....

include C 的时候,A 的子类还不存在呢。如果不考虑子类的子类,可以用 #1 楼 的方法,覆盖 Ainherited 方法。

module C
  extend ActiveSupport::Concern

  included do
    def self.inherited(sub_class)
      sub_class.send :include, SubMixin
    end
  end

  module SubMixin
    ...
  end
end

另外,如果所有子类都差不多,为什么不在父类中直接 mixin 呢?如果有些东西需要子类的特定信息,可以用类似 Template Method 的方式,在运行时的时候代理给子类

感觉你把最重要的信息给隐藏掉了,你是需要在 included 里判断 model 类型,然后根据类型去添加一些方法,或者是调用一些 class macros 吧。

#7 楼, 确实如你说,我需要在 included 里判断 model 类型,然后根据类型去添加一些方法。 目前也 采用#1 楼的做法。非常感谢你们!!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号