从模型内的父模块注入/访问方法

时间:2011-11-24 18:32:38

标签: ruby-on-rails ruby

在Rails中我有以下结构

#.../models/A.rb
module A
  def m
  end
end

#.../models/a/B.rb
class A::B < ActiveRecord::Base
end

这会自动将A作为B的父级。有没有办法在不修改B的情况下执行Bm这样的操作?我知道我可以做一些类似B.parent.m的事情并从那里创建别名,但我必须改变B.
我想以某种方式将A中存在的代码注入B中,但我不知道这种自动关联在幕后的位置。 像

这样的东西
module A
  module C
    def mc
    end
  end
  def placed_as_parent (child) # supposing this is the method called to put this module as a parent 
    super child
    child.include(C) #this is what I would like to do
  end
end

背后的问题是我有一个模块已经在该文件夹的几个模型之间共享,我想在那里为模型添加一些常见的东西,而不必手动包含/扩展每个模块我的模特

[[EDITED]]

我不清楚我的问题。在rails 3中,如果你这样做

rails generate active_record:model A::B

它会生成文件

#.../models/A.rb
module A
  def self.table_name_prefix
    'a_'
  end
end

#.../models/a/B.rb
class A::B < ActiveRecord::Base
end

所以如果我打开一个控制台并输入

A::B.table_name # -> 'a_b'
A::B.table_name_prefix # -> ''
A::B.parent # -> A
A.table_name_prefix # 'a_'

这在模型B中自动发生没有任何包含/扩展。我想要的是在A中包含更多内容并从B访问它,而不像我之前描述的那样更改B上的任何内容。 / p>

2 个答案:

答案 0 :(得分:0)

说实话,我不确定我是否完全明白你的问题,但无论如何我都会试一试。

Module类中有一个钩子,允许您获取对包含模块的类的引用。因此,你可以用它做任何事情。

一个例子:

module A  
  # you can change the class' behavior here
  def self.included(klass) 
    puts "included in #{klass}" 
  end
end

然后使用它:

class B
  include A #this causes the included hook in the module to be called
end

这就是你要追求的吗?

答案 1 :(得分:0)

OP写道:

  

背后的问题是我有一个模块已经在该文件夹的几个模型之间共享,我想在那里为模型添加一些常见的东西,而不必手动包含/扩展每个模块我的模特

这就是我要做的事情:

module Stuff1
   ...
end

module Stuff2
   ...
end

module StuffIWantInSeveralModels
   include Stuff1, Stuff2
end

class X < ActiveRecord::Base
    include StuffIWantInSeveralModels
end

class Y < ActiveRecord::Base
    include StuffIWantInSeveralModels
end

然后,当您想要为多个模型添加新模块时,您只需在一个地方(在StuffIWantInSeveralModels模块中)编写“include”语句。

每个模块应该在lib目录中的自己的文件中,文件名与模块名称匹配,因此Rails自动加载将起作用(例如stuff_i_want_in_several_models.rb)。

这是否达到了你想要的效果?