Sharing models between Rails apps using gems - ruby-on-rails

So I'd like to share models between two Rails apps and do not like the submodules solution (burned me in the past). I'm thinking about using gems to solve this and have this basically working:
Create a gem using jeweler (my_models)
Create a rails app with something in the Gemfile like:
gem 'my_models', :path => '../my_models' so you can avoid constantly packaging the gem, etc.
Use shotgun to constantly reload all the classes (otherwise you can't really edit my_models files without restarting the server/console each time.
So a few questions:
Shotgun is slow, is there a better way in Rails to reload just that one gem each time?
If my my_models ActiveRecord models have dependencies, I put them in my_models gems, will that cause dependency nightmares in my regular app?
What else am I missing on why this could be a bad idea?

If you use a VCS with submodules support (like Git) you could just put models into a different repository and make it a submodule of your Rails apps. That would give you an almost effortless code sharing - Rails wouldn't even know that you are cheating.

Related

Is it possible to create a ruby gem that when added to a rails project simply appends code to its initializers?

I've got some helper code (monkey patches) I tend to carry around from rails project to rails project via simply copying files or pasting code into the initializers folder.
I think a clean way to deploy different categories of my initalizer code would be to simply add gems to my project Gemfile that would do the equivalent of this for me. I'm not very skilled at creating gems or the deeper side of ruby on rails engineering so I just wanted to know if this were possible before I got started with it.
Yes, this is definitely possible. It should be probably enough to make a simple gem, put your monkey-patches there and require them in the gem entry point (e.g., if the gem is called foobar, then bundler will require lib/foobar.rb by default).
There is a guide on creating gems available in Bundler docs. In case you need to interact with Rails application configuration, you can take a look at Rails Engines.

Working on gem within a Rails app

What's the easiest way to work on a plain-ole Ruby gem, and then quickly turn around and run it in a Rails app?
I like to keep application logic out of Rails. Encourages code reuse across projects, and keeps my Rails app clean. It produces, however, an ugly workflow:
Test my gem. rake test
Build my gem. gem build ...
Upload gem to private repository (currently using Gemfury). fury push ...
Update my gem from within Rails (bundle update ...)
Run my Rails code.
Yuck. I'd like to simply save my file in the library, and then watch it work in the Rails project.
Clojure's Leiningen has a concept called "checkouts", allowing you to work on several libraries within one.
Techniques, anyone?
Use Bundler's path directive.
gem 'my_gem', :path => "~/my_gem"
You'll still have to restart the Rails server every time your code changes to reload it, but you won't have to go through the whole build-and-publish step for each revision. Be sure to update your gem reference to something production-worthy before pushing your code.

db:migrate for a Models gem

So we abstracted our models into a gem because multiple applications use the same model set. The trouble is performing creating and performing migrations. Because it is a gem we basically removed rails.
It can't perform rails g or rake.
If we try to keep the config and script folder which allows that, the other applications will complain when they use the models gem.
We're hacking around this by allowing one specific application to perform all migrations.
Perhaps the better question is: What is the best way to modularize common models such that you retain rails g and rake db:migrate?
I probably explained this poorly, please ask any questions.
Thanks,
Justin
Are you using version control? You could look into just using a git submodule for the models folder which would allow you to use rails generators on all applications and keep them all in sync. Basically a submodule is a git repository inside an existing repository.
The commands are simple as well, to get started look into this guide here overall it should help you reduce the complexity of your application.

How can I create a rubygem and test it in a rails application at the same time?

I want to learn how to create a rubygem with a generator etc.
When I create a gem, do I create a separate project?
The reason being, since it will have generators and hook into the lifecycle of a Rails 3 application, I want to create a test rails 3 application at the same time to see how things are working etc.
Can someone outline what I should do to do this?
For example, I'm using git, so what I want to do is, when I run a generator for my gem and it doesn't do what I want, I can then easily rollback to the previous version using git.
This will be a simple gem, just trying to get a feel for things and how I can hook into various parts of rails etc.
Use bundler to create the new Gem with the following command:
bundle gem foogem
Then go to the Gemfile of the application you're going to use and add something like the following:
gem 'foogem', :path =>'/path/to/foogem'
In this way you can easily test your gem inside your rails project.

Building a ruby gem for Rails applications

As a Rails developer I feel a bit stupid asking this question but hopefully I will learn something new and someone can put me out of my misery! In my rails applications I use (other peoples) gems all the time, I also use plugins from the community or my own.
I understand the benefits of use gems over plugins as they are version-able, segmented, system wide, easier to manage and share etc etc but I don't really know how to go about making a gem for my rails apps!?
Do you always start with a plugin and convert it to a gem, I've seen the words 'package it as Gem'. Also the gem I'm thinking of building would be no good in a normal ruby program, it's only useful to rails apps. I'm not even sure if the semantics of that make sense, 'RubyGem' that will only work in a rails application!?
I would like to create a gem (if that's what I should use?) for a discrete piece of functionality for my rails apps. It will need to add a database migration, new routes and provide controllers and views or useful view helpers. I'm know I can achieve this via a plug-in but would just like to know how/why to do it as a 'Ruby Gem'?
To avoid the risk of Over-engineering, I usually start with the feature I need directly into the application. Then, as soon as I need to use the same feature into another project, I check whether it is worth to extract it into a plugin or even a separate application providing an API.
Plugins and Gems are often interchangeable. Gems provides several significant advantages in terms of reusability and maintainability.
On the other side, there are some specific known issue. For instance, a Rails app actually can't load rake tasks defined into a plugin packaged as a Gem.
Almost every Rails plugin can be packaged as a Gem.
For instance, take my tabs_on_rails plugin.
You can install it as a Gem specifying the dependency on environment.rb. Or you can use script/plugin install command as you would expect.
If you want to achieve the same result, make sure to follow the standard Gem layout and provide the init.rb initialization script required by Rails.
Also, you might want to create an install.rb and uninstall.rb file to include the post-install and post-uninstall hooks when the plugin is installed as a standard Rails plugin.
Last but not least, if you package a plugin as Gem you can reuse it in non-Rails projects and provide Rails-specific initializations using the init.rb file. Non-Rails applications will simply ignore it.
If you want to make a plugin for Rails, https://peepcode.com/products/rails-2-plugin-patterns gives you a good start. After that, make the plugin into a gem.
To make a gem, this resource http://railscasts.com/episodes/183-gemcutter-jeweler will be helpful.
As of 2013 you'll want to use Bundler and the following tutorials:
#245 New Gem with Bundler -
RailsCasts
Make your own gem - RubyGems
Guides
Take a look at Jeweler. Jeweler gives you a set of rake tasks to make gem versioning and building very easy.

Resources