Ruby / Rails - 动态指定类的连接属性

时间:2012-12-17 22:02:05

标签: mysql ruby-on-rails ruby module

我们的应用从各种Feed中接收数据。

以数据库的形式向我们提供了一个Feed。因此,我们将此数据库与我们的app数据库存在于同一MySQL服务器实例中。此Feed数据库的进一步更新以增量形式提供,必须处理到完整的Feed数据库中。

所以,我有:

  • app_db
  • feed_db
  • feed_delta_db

feed_dbfeed_delta_db具有相同的结构(表,列等)。

有时我需要访问feed_db,有时我需要访问feed_delta_db

在我开始接收增量之前,我这样访问feed_db

module Feed
  module Db
    module InstanceMethods
      def something
        puts 'pffffft'
      end
    end

    def self.included(receiver)
      receiver.send :include, InstanceMethods
      receiver.instance_eval {
        establish_connection(
          {
            :adapter => "mysql2",
            :database => "feed_db",
            :username => "mysql_user",
            :password => nil,
            :host => "localhost"
          }
        )
      }
    end
  end

  class FeedModel < ActiveRecord::Base
    include Db
    self.abstract_class = true
  end

  class Sometable < FeedModel
    set_table_name "sometable"
    belongs_to :someothertable, :foreign_key => "SomeothertableID", :primary_key => "id"

    def name
      "#{field1} #{field2}"
    end
  end
end

现在我可以复制feed_delta_db的所有代码,我唯一需要更改的是连接详细信息中指定的数据库。

但这不是干,是吗?

结果将是我想要的。我可以像这样访问单独数据库中的表: Feed::SometableFeedDelta::Sometable

如何将我的类定义分离到他们自己的文件中,并将/ require / what它们分成不同的模块(或类),这样我就可以随意访问db?

如果有什么不清楚,请告诉我。

感谢。

1 个答案:

答案 0 :(得分:1)

我将定义一个通用父类,然后在子类

中切换db
class GenericParent < ActiveRecord::Base
  self.abstract_class = true
end

class Feed < GenericParent
  establish_connection :feed_db
end

class FeedDelta < GenericParent
  establish_connection :feed_delta_db
end

# config/database.yml
development:
  ...

feed_db:
  ...

feed_delta_db:
  ...

尊重不同的环境是明智的。因此,establish_connection可能看起来更像:

class Feed < GenericParent
  establish_connection :"feed_#{Rails.env}"
end

这将允许您在数据库中拥有feed_development,feed_staging,feed_production等部分.yml