【问题标题】:Extending application's model in rails engine在 Rails 引擎中扩展应用程序的模型
【发布时间】:2016-04-19 11:51:35
【问题描述】:

我有一个定义了一些模型的应用程序。我想将一些模型的功能(例如添加方法、添加关联)从应用程序扩展到我的引擎。 我尝试在引擎中添加一个与我的应用程序模型同名的模型,Rails 会自动合并它们,但是它不起作用。

例如: (应用程序的模型)

class Article < ActiveRecord:Base 
 def from_application
    puts "application"
 end
end

(Inside my Engine)
module MyEngine
  class Article < ::Article
    has_many :metrics, :class_name => 'Metric'
  end 
end

当我尝试访问 @articles.metrics 时,has_many 关联未应用于我的文章模型。有任何想法吗 ?

【问题讨论】:

  • 我认为 class_eval 是您正在寻找的。我没有这方面的经验,但最近读了这篇文章:edgeguides.rubyonrails.org/…
  • @Arun Kumar M,您的指标模型是否与 Articles 有关联。您的迁移情况如何,您的 Metric 表是否包含 article_id。您收到的确切错误消息是什么?
  • @OlalekanSogunle 是的,我愿意!我仔细检查了它:)
  • @siax:检查了那个链接。但它不适用于关联
  • 你能添加你得到的确切错误信息吗?

标签: ruby-on-rails ruby ruby-on-rails-4 ruby-on-rails-plugins rails-engines


【解决方案1】:

你有正确的想法并且很接近。但是你的实现有点偏离。

通常,您的引擎应该了解您的宿主应用程序。这样,您的引擎和主机应用程序将保持松散耦合。因此,引擎中的类应该从宿主应用中的类继承。 (顺便说一句,我相信你的方法行不通,因为 ruby​​ 进行持续查找的方式,但这是一个不同的讨论。)

改为使用included hook。在主机应用程序中,您可以执行以下操作:

  class Article < ActiveRecord:Base 
    include FooEngine::BarModule

    def from_application
      puts "application"
    end

  end

在引擎内部:

  module FooEngine
    module BarModule
      def self.included(base)
        base.class_eval do 
          has_many :metrics, :class_name => 'Metric'
        end
      end
    end 
  end

当 ruby​​ 解释器将 FooEngine::BarModule 包含在 Article 中时,它将查找并运行(如果找到)FooEngine::BarModule 中的 self.included 方法,将 Articleclass 作为 base 传递。

然后您在 base (Article) 上调用 class_eval,这将重新打开 Article 类,以便您可以添加方法或任何您想做的猴子业务(定义新方法 原位,包括或扩展其他模块等)。

在您的示例中,您调用has_many 方法,该方法将创建has_many 提供的各种关联方法。

如果 (a) 您要通过引擎添加大量与指标相关的功能,(b) 您希望有很多类使用指标相关的功能,并且 (c) 您想要一些的功能因类而异(包括在内),您可以考虑创建一个acts_as_having_metrics(或类似的)。一旦你沿着这条路走下去,它就是一个奇妙的元编程的全新世界。

祝你好运。

【讨论】:

  • 所以如果你稍后安装 FooEngine 你必须回到每个模型(例如文章)并添加 "include FooEngine::BarModule" ?这似乎有点奇怪。还有其他方法吗?
【解决方案2】:

您的指标模型是否与 Articles 有belongs_to 关联。

您可能希望给关联的另一方 Metrics 一个 belongs_to Articles 以使其正常工作。此外,请确保进行迁移以在指标表中保存articles_id。一切都应该正常。

【讨论】:

  • 是的,我愿意!我有协会
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多