2010-01-12 35 views
1

我有一个问题,使用acts_as_textiled和has_foreign_language插件在一起。在rails模型中扩展现有的属性获取器

的TextElement我在我的应用程序模型

class TextElement < ActiveRecord::Base 
    has_foreign_language :value 
    acts_as_textiled :value 

HasForeignLanguage

def has_foreign_language(*args) 
    args.each do |field| 
     # Define the Getter 
     define_method(field.to_s) do 
     . 
     . 
     . 

ActsAsTextiled

def acts_as_textiled(*attributes) 
. 
. 
. 
    attributes.each do |attribute| 
    define_method(attribute) do |*type| 
. 
. 
. 

这两个插件都使用define_method,以及哪种方式我在TextElement中调用mixin,后者覆盖之前定义的getter。

有没有办法保存现有的getter并在新定义的getter中调用它?类似于使用超级如果他们被遗传。

我已经分出了这些插件,所以这里都是公平的游戏。

所有帮助表示赞赏。

回答

1

或者,您可以使用alias_method_chain重写这两个。

def some_class_method_that_overrides(*columns) 
    columns.each do | c | 
    overriden_name = if instance_methods.include?(c) 
     alias_method_chain(c.to_sym, "extra") 
     "#{c}_with_extra" 
    else 
     c 
    end 
    define_method(overriden_name) do ... 
    end 
    end 
end 
+0

你知道这里发生了什么吗? alias_method_chain的文档非常混乱。 –

+0

请谷歌为alias_method_chain,它有什么解释负载 – Julik

0

你可以尝试让其中一个插件修饰属性而不是重新定义它们。喜欢的东西(我在这里延伸对象,但你可以扩展任何需要它):

class Object 
    def decorate!(attr) 
    method = self.method(attr) 
    define_method(attr) do |value| 
     result = method.call(value) 
     yield(result) 
    end 
    end 
end 
与装饰

所以!你可以试试这个在acts_as_textilized

def acts_as_textiled(*attributes) 
. 
    attributes.each do |attribute| 
    self.decorate!(attribute) do |return_value_of_decorated_method| 
    # decorate code here 

或沿着这些线。未经测试,您可能需要调整,但基本想法在我的想法。

+0

谢谢戴夫我明天会告诉你,如果它能完成这项工作,请告诉你。 –