Richlewis
Richlewis

Reputation: 15384

Create a Gem for Models to be shared between two applications

I have never done this before and am not sure where to begin. I have two applications, one read and the other read/write. I have been advised that I can share the same database between the two applications and that I should create a gem of my models from the read/write app to be used in my read only app.

This sounds like a great solution as it means I won't have to duplicate my code between the two apps. Where to start though? I would really appreciate an explanation and some guidance on what to do here, almost a mini how-to guide if possible, or at least somewhere to look?

So having done some more reading I can see that you can use Bundler to create a gem

bundle gem name-of-my-gem

and I can use the gem like so, by placing it in each application

gem "name-of-my-gem", path: "path/to/gem/dir"

How do I actually tell it which of my models I want to put into a gem though?

Upvotes: 4

Views: 1794

Answers (1)

Carl Zulauf
Carl Zulauf

Reputation: 39568

How you structure the gem is pretty much up to you, but here's how I would start:

name-of-my-gem/
.. lib/
.... name-of-my-gem.rb
.... models/
...... all_of_your_models 

Your models gem should have a .rb file that loads any models stored in it. If this file is named after the gem and placed in the lib/ directory of the gem, it should be auto-loaded by bundler. This file might look something like this:

require "models/customer"
require "models/order"
# ...

You might also do something fancier here, like grab the list of files in the models directory and load each one so you don't have to add each new model to this file. Up to you.

Each models/ file would look exactly the same as a model in your rails app:

class Customer < ActiveRecord::Base
  has_many :orders
  # ...
end

You can copy any model classes you want to share out of app/models/ in the rails app they currently reside in and paste them into models/ in your gem. Then, you simply need to update the gem in each app (run bundle update name-of-my-gem in each) and you should be able to take the model out of app/models/ and it should still work since it will be loaded from your gem.

One downside of this approach is that rails can no longer reload the model after you make changes. After changing a model in your gem you will need to run bundle update name-of-my-gem, and restart the rails server. I would suggest fleshing out most of a model's functionality in one app first to take advantage of rails code-reloading, and when its pretty stable move it into the gem.

You could also give your gem code-reloading powers, but that gets rather complicated and I've never done that.

Upvotes: 8

Related Questions