Building a ruby gem for Rails applications - ruby-on-rails

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.

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.

Advice on HTTPS connections using Ruby on Rails

Since I am developing a "secure" OAuth protocol for my RoR3 apps, I need to send protected information over the internet, so I need to use HTTPS connections (SSL/TSL). I read How to Cure Net::HTTP’s Risky Default HTTPS Behavior aticle that mentions the 'always_verify_ssl_certificates' gem, but, since I want to be more "pure" (it means: I do not want to install other gems, but I try to do everything with Ruby on Rails) as possible, I want to do that work without installing new gems.
I read about 'open_uri' (it is also mentioned in the linked article: "open_uri is a common exception - it gets things right!") that is from the Ruby OOPL and I think it can do the same work.
So, for my needs, is 'open_uri' the best choice (although it is more complicated of 'always_verify_ssl_certificates' gem)? If so, can someone help me using that (with an example, if possible) because I have not found good guides about?
You should find the best tool for the job and use it. You should not try to limit your usage of libraries to just Rails and the Ruby standard library, because these two alone will not always provide you with everything you need. As you have indicated, you found the right tool for the job - don't reject it just because it's not part of "official" Ruby or Rails.
You can easily manage which gems your application needs with Bundler, such that everyone on the team is, with a single command, always able to install and run the application, including automatically installing all gem dependencies. Rails 3, by default, integrates with Bundler and expects that you will use Bundler to manage all your gem dependencies.

What kind of things should go into a Ruby gem as opposed to a Rails plugin?

I have a set of functionality that I am considering packaging so as to use them in multiple projects, but I can't decide whether to choose a gem or a plugin. What is the difference? Which one should I choose?
Gem is currently acknowledged as the 'best practice' for Rails. (You can also package as a gem and include an install.rb so that your project can be optionally be installed as a plugin - see this Rails dispatch article).
Basically the only reason to go with a plugin is if your users will want to be able to modify the code more often than not, as it stores a copy in vendor/plugins. However, with the advent of bundler it's pretty simple to store your gems per repository as well and modify them.
If you go with gems, you get the advantages of dependencies, versions, and the functionality that rubygems.org offers for searching, alerts and so on.
Definitely make it a gem!

Should I create a Ruby gem or plugin

I have some logic code that is literally cut and pasted across several different sites I own (it's code that interacts with a web API I've created). Considering that this isn't DRY and that when I update one thing I want it to update across all my sites I wanted to move this to a gem or a plugin. My main question is which one is the best to use in this scenario?
One big sticking point is that this code is private and shouldn't be made available to just anyone.
Thanks
Gems are the de-facto standard for packaging and releasing Ruby libraries.
There used to be two major drawbacks to using gems instead of plugins in Rails applications. Gems did not have access to all the functionality that plugins had. For example, in Rails 2, gems could not directly add rake tasks to your application. In Rails 3, plugins and gems are completely equal.
The second drawback was that gems were harder to bundle with your application. This has been resolved a while ago by rake gems:unpack:dependencies. It copies all gems your application depends on to your app's vendor/gems application. If you deploy these with your application, there is no need to install them on remote servers. In Rails 3, the new gem bundler further improves this mechanism. It even allows you to bundle Ruby C-extensions!
Also consider the things that cannot be done with plugins: versioning, packaging, dependency management, extending Ruby, etc.
In my opinion there is no serious reason to use plugins instead of gems anymore. The last advantage of plugins will be void when Rails 3 is released. Spread the word, and help everyone convert their plugins to gems!
Let's see Pros / Cons:
Gems
Pros
Easier to update the version (gem update)
Code encapsulated and available for all applications on the machine
Cons
Webapp code and gem code aren't encapsulated together.
You have to install every gem on each pc the application will run.
You have to install rubygems on each pc, too.
Maybe it's nedeed to be sudoer to install the gem.
Plugins
Pros
Code encapsulated within the application
You don't need special rights on the machine to work.
You don't need rubygems.
Cons
More difficult to update the code than gems
You have to install the plugin on every application that will need it.
I think this are all the differences. The decission now is yours :)
For me both solutions are OK, you have to think about your needs.
Hope that helps.
Will you ever have more than one version of this API being used in production at the same time?
If not, the simplicity and flexibility of a plugin is probably easier, especially if you use a tool like Piston to install/update the plugin from a centralized code repository.
Gems are not too convenient for private stuff, imo, with the way they're distributed. And distributing them by hand avoiding the gem hosts is an overhead. If it was me and I had a piece of private code I need to use in a bunch of places, I'd simply throw it into lib/ dir as a fake git submodule. Then pull once in a while.

Reusing Ruby code across several Rails applications

I have developed a simple library in Ruby and need to use this in several Rails applications (some of which are not built yet). What is the best way to easily add this Ruby library to several Rails applications as and when required? Our team is running Ubuntu and our repository is Mercurial.
Should I use a...
Rails plugin? This would be my first
choice but it appears not to support
Mercurial??
Ruby Gem?
Custom Rake script?
Other options??
Any pointers would be much appreciated!
Ruby already has an established mechanism for code sharing i.e. RubyGems. Jeweler makes Gem creation easy. I'd recommend that you check it out.
Make a gem or a plugin. Gems are better in my opinion, easier to manage.
My rule of thumb:
If it doesn't depend on rails, make it a gem.
If it depends on rails, make it a plugin.
Make a Rails plugin. It doesn't "support" Mercurial in the sense that you can't do script/plugin install $REPO_URL and have it work automatically, but if it's for your own use, then you won't miss that feature.

Resources