Ruby on Rails扩展了gem的类并更改了其继承类

时间:2018-08-16 09:53:20

标签: ruby-on-rails ruby rubygems extending-classes impressionist

我有一个基于Ruby on Rails构建的Web应用程序。 在此应用中,显然使用了不同的宝石。 我到了要扩展某些特定gem的类并为其添加方法的地步。

现在我有一个用例,我想扩展gem的类,但我不想更改方法,而是要更改其继承类 让我们以印象派宝石为例:

IV在我的应用程序中创建了一个新类-app / models / impression.rb

class Impression < ActiveRecord::Base
  establish_connection(ENV[App_LOGS_DB'])
end

我想更改继承以使用我的自定义类LogsBase

class Impression < LogsBase
end

LogsBase类的定义如下:

class LogsBase < ActiveRecord::Base
  establish_connection ENV['APP_LOGS_DB']
  self.abstract_class = true
end

在尝试运行服务器时,引发以下异常:

/gems/impressionist-1.6.1/lib/impressionist/models/active_record/impression.rb:5:in `<main>': superclass mismatch for class Impression (TypeError)

根据我的理解,这基本上意味着gem的印象等级定义与我自己对该印象的定义之间存在冲突。

任何人都可以帮助我找到一种方式来更改Impression类的继承类,同时仍然保留该类的行为并使服务器正常运行吗?

PS:所有这些操作的目标是将展示数据写入另一个数据库(日志数据库)中,而不是写入主应用程序数据库中。为了做到这一点,我需要建立与日志数据库的连接,但是如果直接在Impression类中执行该操作,则会如以下链接所示那样炸毁我的数据库连接池:

https://www.thegreatcodeadventure.com/managing-multiple-databases-in-a-single-rails-application/

这就是为什么我需要抽象的LogsBase类。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

免责声明:请勿这样做!

我能想到的唯一方法是讨厌的hack,既不可靠也不可靠,它与外部gem的较新版本不兼容。由于Ruby不允许重新定义类的祖先,因此您可以(请不要):

  1. 抓住原始/gems/impressionist-1.6.1/lib/impressionist/models/active_record/impression.rb文件的内容。
  2. 将其复制粘贴到您的/blah/foo/impression中。
  3. 使您的班级明确地加载impressionist/models/active_record/impression
  4. 在文件未设置原始类的第二行。

类似这样的东西:

require 'impressionist/models/active_record/impression'

Object.send :remove_const, 'Impression'

class Impression < LogsBase
  # ORIGINAL CONTENT OF THIS FILE
end

答案 1 :(得分:1)

没有(明智的)方法来重新定义红宝石的基类。这是可能,但只能通过怪异的骇客进行。

我建议在这里选择两条路线之一:

  1. 派生库,并使基类可配置(具有向后兼容性)。
  2. 请勿通过继承执行此操作。而是将establish_connection ENV['SPLACER_LOGS_DB']放入模块,并将include放在类中。

我现在倾向于使用选项2,因为这是一种快速/简单的解决方法,应与应用程序的其余部分很好地配合。