I have two rails apps running off the same database, one which runs the client and one which provides an admin interface.
Both the apps have the exact same models defined save for small number of differences. Its tiresome for me to duplicate the vast majority of changes in the models on to both apps.
One way for two apps to use the same model info is to symlink the model folder from one app to the other, but I cant do that due to the few differences in code (e.g an extra validation on the client).
Is there a simple way I can move out the differences so I can keep the common code in one place?
Why not doing it OOP way, e.g. creating a separate base class (in a separate directory) and then inheriting from it in both projects, so the differences are in the inherited class.
So, you have
class BaseModel < ActiveRecord::Base
in "common" subdirectory, and then you have
class AdminBaseModel < Common::BaseModel
in admin project and
class UserBaseModel < Common::BaseModel
you might need
set_table_name "basemodel"
so Rails knows which table to open.
svn:externals or git submodules are definitely the way to go for this sort of situation.
Of course, you'll want to be able to test them in both apps, so you should share your model tests or specs as well. But remember that models often depend on plugins, so you'll want to share your plugins folder, too. And you probably want the same gems and the same version of Rails, so your best bet is to share all of vendor. Oh, and sometimes your code in lib modifies your models, so you'll want to share that. Oh, and be sure to share any custom configuration in the environment files.
And you'll want to have a continuous integration server set up to run your test suite on both applications in case changes to the model tier in your master application break your other application.
But I mean, once all that is worked out, svn:externals or git submodules are definitely the way to go for this sort of situation.
Update (some years later)
Rails Engines are probably the best bet currently for reliably sharing model code between multiple applications. They can be gemified and included in the Gemfile
of each application.
I work on a project that has a similar issue and we used svn:externals to share the model code between two apps.
Basically you have the models diretory in one svn project and use an external in the other project to share the code. You can edit code in either project and it will be updated when you run svn up
in the other project.
As far as Rails and your build scripts are concerned the two models directories are completely separate.
Yes, symlink the models directory, but then add an environment variable to your environment.rb for each instance. Then your models can know which instance is using it and include additional validations or what not.
in environment.rb:
APP_INSTANCE = "app1"
in model.rb
validates_length_of :name, :within => 3..100, :if => :is_app_one?
def is_app_one?
APP_INSTANCE == "app1"
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With