扩展 Rails 模型中现有的属性 getter

发布于 2024-08-17 18:54:46 字数 837 浏览 12 评论 0原文

我在同时使用acts_as_textiled 和has_foreign_language 插件时遇到问题。

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 中调用 mixins,后者覆盖了之前的 getter定义的。

有没有办法保存现有的 getter 并在新定义的 getter 中调用它?如果它们是继承的,则与使用 super 类似。

我已经分叉了这些插件,所以一切都是公平的。

感谢所有帮助。

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|
.
.
.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧梦荧光笔 2024-08-24 18:54:46

或者,您可以使用 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

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
预谋 2024-08-24 18:54:46

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

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

或者类似的东西。未经测试,您可能需要进行调整,但我认为基本思想就在那里。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文