开发者

Extend an existing attribute getter in rails model

i have a problem using acts_as_textiled and has_foreign_language plugins together.

TextElement my model in my app

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|
.
.
.
开发者_StackOverflow中文版

Both plugins use define_method and which ever way round i call the mixins in TextElement the latter overrides the getter previously defined.

Is there a way to save the existing getter and call that in the newly defined getter? similar to using super if they were inherited.

I have forked these plugins so all is fair game there.

All help appreciated.


Alternatively you can rewrite these two using 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


You could try having one of the plugins decorate the attributes instead of redefining them. Something like (I'm extending Object here but you can extend whoever needs it):

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

So with decorate! in place you might try this in acts_as_textilized

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

Or something along those lines. Untested, you may have to tweak, but the basic idea is there I think.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜