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.
精彩评论