Heroku follow : how to handle multiple databases in a Rails app?

China☆狼群 提交于 2019-12-03 00:39:34

So... I like this solution:

module Analytics

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

  class User < Base; end

  class Product < Base; end

end

Now you have models that all connect to your analytics database (the follower).

If you need to share scopes or methods between your analytics app and your normal app, you could put the shared code in a mixin, and then just include that in either of your Analytics or normal models.

Alternatively you can just call .establish_connection on the models you need to use for analytics in the controller prior to using them for analytics, but I don't know if that will muck up your connection for other normal web requests, requiring you to set it back to your normal database connection on the next request...

UPDATE: Another idea just struck me:

class UserBase < ActiveRecord::Base
  self.abstract_class = true
  # all your user model code goes here
end

class User < UserBase
  establish_connection(Rails.env) # connect to your normal database
end

class AnalyticsUser < UserBase
  self.table_name = 'users'
  establish_connection(ENV['ANALYTICS_DATABASE_URL'])
end

This allows you to share all the code between your models whether they are for analytics or normal web requests, but set a different connection depending on the model name.

Also, as a sidenote, if you don't want to set up a follower in your development environment, just set ENV['ANALYTICS_DATABASE_URL'] in your development.rb:

ENV['ANALYTICS_DATABASE_URL'] ||= 'postgres://localhost/myapp_development'

And obviously, on Heroku, you'll need to rename or set the config var for your ANALYTICS_DATABASE_URL to whatever the DATABASE_URL for your follower is.

To better answer this question : Heroku has now posted an "official" way of dealing with this situation using the Octopus gem :

https://devcenter.heroku.com/articles/distributing-reads-to-followers-with-octopus

With this gem it's possible to create either a fully replicated model, or execute only a block on the follower :

Octopus.using(:slave_two) do
  User.create(:name => "Mike")
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!