17

We’ll be releasing shortly a companion Rails application to our existing Rails app. We will be running the companion app alongside our existing app on the same servers.

My question concerns the databases. My hosting provider generally would configure a 2nd distinct database for the new application - secondappname_production. However, there are a series of shared tables between the applications. These shared tables are also maintained by a series of cron jobs. I would love to avoid duplicating these tables (and thus the cron jobs) if at all possible.

Is there a way that I can put these shared tables in perhaps a shared database that both Rails apps can leverage? Any suggestions as to how to configure that or documentation pointers?

Thanks so much!

EDIT: To clarify why I don't want to run both apps out of the same DB: Both apps have models of the same name (yet different attributes of the models, etc.), so I would prefer to not run both out of the same DB....

3
  • Isn't the point of database tables is that they can be shared? Or is this a 'ask your provider' question? Commented Jan 12, 2010 at 3:06
  • I understand that database tables can be shared in principal, however, I am interested in Rails best practices as they may relate to this situation. Both apps have models of the same name (yet different attributes of the models, etc.), so I would prefer to not run both out of the same DB. Hope that clarifies... Commented Jan 12, 2010 at 3:09
  • Bear in mind that you'll be sacrificing the ability to perform in-database joins when the tables are on different databases, and that your two apps could have models with the same name but which reference tables in the same database with different names. Commented Apr 7, 2015 at 14:08

2 Answers 2

27

You can have some models in one database (the ones that you want to share), and others in the new app's own database (so they don't collide with the existing app).

To specify a different database for a particular model, try something like this:

class SharedModelBase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection(ActiveRecord::Base.configurations["shared_db_connection_#{RAILS_ENV}"])
end

Now, use this as a base class for your shared models, and you should be good to go.

Part of your question is best practices, so a couple of other options.

One option is to not even try to access to the db directly, but instead build an integration between the apps using ActiveResource. Have the original app provide a RESTful interface to these tables, and consume it in the new app, and don't share the db at all. I like this option, but may not be clever for your situation.

Another option is to refactor these shared tables into their own database, and have both the rails apps access that db. You could even end up writing services (e.g. restful interface) to this shared data to be used by both apps, and then you are nicely decoupled.

Consider the complexities of when this shared db structure changes. If you are sharing the tables directly, both rails apps could have to be changed simultaneously to accommodate the change - you have linked your release schedule now, these apps are now coupled. If you wrap the access to the db in services, this can provide abstraction as you can serve both the old structure and new structure simultaneously by deploying the new updated service at the same time as the old service interface. It all depends on your app if such complexity is worth it.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow! Thanks so much! Great information and thoughts, especially around the best practices/options. This provides some great options to discuss with the rest of my dev team. Much appreciated!
0

I think what you want is share model,not only database table,in rails table is model based.

create main rails app -->rake g model User name:string->rake db:migrate
create shared rails app 
-->rake sync:copy 
-->(DO NOT generate same model in shared app, also do not db:migrate)
-->config/generater shared
controller and router.rb file(dependend your requirement)

sync.rake(appshared/lib/tasks/)

namespace :sync do

      desc 'Copy common models and tests from Master'
      task :copy do
        source_path = '/Users/ok/github/appDataTester/appmain'
        dest_path = '/Users/ok/github/appDataTester/appshared'

        # Copy all models & tests
        %x{cp #{source_path}/app/models/*.rb #{dest_path}/app/models/}
        %x{cp #{source_path}/test/models/*_test.rb #{dest_path}/test/models/}

        # Fixtures
        %x{cp #{source_path}/test/fixtures/*.yml #{dest_path}/test/fixtures/}

        # Database YML
        %x{cp #{source_path}/config/database.yml #{dest_path}/config/database.yml}
      end
    end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.