This may be a very lame question, but still I am confused when should I use a gem and when should I should use a plugin in my project.
What's the basic difference between them?
The basic difference is a gem is something that needs to be installed on the system running your Rails application, whereas a plugin is deployed along with your application. More specifically, plugins live in vendor/plugins whereas gems need to be install using rake gem install gem_name.
As for when to use each, gems tend to be easier to keep up to date, but more specifically, some gems use native C code and are compiled specifically for a given operating system (such as Nokogiri). These need to be installed as gems as they will not work when moved to another system. Whereas some things like acts_as_commentable use straight ruby code and can be moved from system to system.
From RailsGuides:
A Rails plugin is either an extension or a modification of the core framework.
From Rubygems.org:
A gem is a packaged Ruby application or library.
So, the biggest difference between the 2 is that Rails plugins are specifically made for use within Ruby on Rails applications, whereas gems aren't.
For example, let's look at Geokit.
The gem (geokit-gem) provides the fundamental location-based operations.
The Rails plugin (geokit-rails) mixes location finders into ActiveRecord.
Here you can see that the gem provides the core of Geokit. This gem can be used anywhere, not just a Rails app. The plugin provides additional features for those who are using geokit within a Rails app. In this case, using the plugin as well as the gem is optional.
When you install a plugin in a project it can be used only in the respective project. But if u install a gem, it can be used by every project. This is the main difference of Gem & Plugins.
Gems are distributed by rubygems, which is the official ruby library package manager. Plugins is a (probably hacky) way for rails plugins. I recommend you using gems whenever possible, due to dependency resolution. Rails3 ecurages that by packing with Bundler.
I use gems whenever a gem works as I wanted to and plugins when I want to do a custom change for a specific rails application and not affect all of my system.
Related
Just a bit of background, I come from a strong C#/staticly typed background. Therefore I tend to think in terms of .dlls. So if I was working in a project, I'd reference my required dlls and that would be that.
Being new to Ruby and Rails I find I might be doing something wrong. For example, I create a Rails app at home using the gems I have locally. Using a different computer (say a work computer) I attempt to work on the project only to find I'm using different versions of the gems. After carrying out a bundle install I'm back to a working project.
The issue I have with this is that my gem library becomes 'messy'. I end up with several versions of the same gem. Is this the way others work? When using a gem (from a require) will it default to the latest version? I feel as if I'm not managing the dependencies correctly, though as I've mentioned I'm new to the world of Ruby.
Should I just include my dependencies, then perform a bundle install each time I have different/missing dependencies? What happens if I wish to upgrade to a newer version of a gem? Would it be a case of updating the gemfile that bundle uses and getting on with it?
Yes, bundler is the way to go to work with dependancies with Ruby on Rails. Why ? First, because it's shipped with it (at least for version 3.0). Second, because it's simple as hell (unlike maven with Java).
A non exhaustive list of feature :
it lets you declare one or many gem repository to fetch gems from
to group your dependencies by environment (development, production...)
to specify version you'd like
and so on. For more on this, check this http://gembundler.com/rationale.html
Regarding your question : yes, bundler will take the latest version available is none is specified.
Also, I would add a disavantage : you cannot specify a gem version depending on the OS. For example, nokogiri has a linux version AND a win version.
The default behaviour when requiring a module in a gem is to assume you want the latest version of the gem if you have more than one installed. You can change this by specifying which version you want in a specific application like this:
gem "rails", "2.3.8"
Before you require anything from the gem. This ensures that this application will use the specified version of the gem, even if a newer one is installed.
You can of course clean out obsolete versions of your installed gems whenever you don't need them again, or if you use bundler consistently: just wipe everything and run bundler again to get just your required gems installed.
Another useful tool is the Ruby Version Manager (RVM), in addition to handling different versions of ruby it provides a feature called gemsets which allows you to isolate different applications or environments from eachother. That is App A can have its separate gemset with all its required gems, and App B have another gemset with only its required gems. This will reduce the clutter in your dependencies quite a bit.
I'm new to Rails and I'm confused about concept of gems & plugins. Can anyone explain them for me?
Plugins are just libraries loaded from a specific directory, gems are loaded via Bundler or RubyGems directly.
Where this really makes a differences is maintenance and management. What happens when you want the latest and greatest authlogic plugin, well you need to update the files in your directory. That doesn't sound so bad when it's one plugin, but what about something that constantly updates? There was/is an existing system for code packaging and distribution (RubyGems), which lends itself to managing such things.
Consider the authlogic example again, what happens if the new version requires some other dependency now? With RubyGems the gem file explicitly defines that relationship, the plugin system does not and such a definition would've been redundant.
With the advent of Bundler in rails 3.x it's become very easy to manage and distribute the gems that your project uses.
TL;DR: Plugins are basically gems without the packaging information.
Plugins are being used less and less so stick with gems. Gems and plugins can do exactly the same thing so that is why they are confusing. However the differences are how they are organized and most importantly how gems are managed such as bundler or config.gem. It is much easier to manage gems and their versions. Plugins must be installed in the vendor folder where as gems can also be installed in that folder if they need to be customized or they can be installed in a gem directory as long as rails understands where that directory is located. When rails started most people used plugins to added functionality but developers quickly realized that gems offered a better way to package and update libraries so most plugins have migrated to gems and fewer plugins are being built.
Gem and Plugin
gem is stored in lib files
A Gem is a packaged Ruby application using the packaging system defined by RubyGems.
plugins are stored in vendors/plugins
A Rails plugin is a packaged Ruby application that extends the core Rails framework.
I am facing some problem with rails gem when deploying to a differet machine.It requires some extra work on installing gem.Which is most suitable for a rails project.Plugin or Gem.
For Some gems there is no corresponding plugins found.
I am searching for advantages of using plugin over gems and vice versa.
You can unpack gems to your Rails application, which will make sure that they are deployed together with your application:
rake gems:unpack:dependencies
Now you no longer have to install the gems on the server you deploy to. This already takes care of most of the deployment issues. Most others are solved by Bundler, which will be included with Rails 3.
If you can, use gems over plugins. Gems are generally easier to manage, because their versioning is superior to plugins. For public Rails extensions, I see no reason to use plugins instead of gems, but some authors only offer one of the two. In that case you have no choice.
I usually always use a plugin if it is available as it gets frozen into the project, meaning there are no issues when the project is deployed. You can freeze gems into a project but if they require a native build it causes more hassle than it's worth from my experience.
My understanding is gems are easier to upgrade than plugins.
You should also look into the rails 3 bundler which is used to handle these deployment issues.
For me, plugins are preferred. I've run into many a situation where I'll have an improperly configured environment.rb and gems won't have versions assigned to them. Then the server admin does a:
sudo gem update
And now my rspec tests won't run because the update installed test-unit 1.2.2 and my specific setup needs 1.0.1 (or something).
Same as Title said: What is the benefit for freeze gems in Ruby on Rails?
When you freeze a gem it copies it in to the /vendor directory in your application and the application will load it before it loads a version of the gem installed in the normal rubygems path.
The advantage is that it means when you put your application source code on another machine you have the gem already available to the application without having to install it separately on the machine and you also know that the version of the gem you rely on is available. One disadvantage of this approach is that you can't really do it for gems which have C components which need to be compiled on installation.
There are now other mechanisms for helping manage the installation of gems that your application depends on such as geminstaller which can be used to semi-automate the installation of the gems your appliation relies on.
Typically I create a plugin when I have a module that I know I'm going to need over again in my other projects, however, they could also be packaged as gems.
When should I be building a gem over creating a plugin? Is there any criteria for making the call?
Plugins are becoming obsolete now that you can manage gems via the "config.gem" statement in environment.rb. Gems are available system-wide (not just in one app), and are versioned unlike plugins.
I've converted all of my plugins to gems recently. Easy to do and well worth it.
Rails seems to be moving towards the gem direction. I have converted most of my plugins to gems now. Gems are easier to manage and fit better in the Ruby eco-system. Why do we need two separate systems anyway?
There is still a problem with gems however: it is not possible to add rake tasks to a Rails application from a gem. Probably the same holds for generators, although I'm not sure. If you use these in your plugin, migrating to a gem is not yet possible. Hopefully this gets fixed soon.
you can add generators to rails via gems. it's actually pretty easy, you can just add a rails_generators directory to your gem. (i think other directory names will work - i'm not sure what rails searches for). example: http://github.com/remi/rackbox/tree/a21c21667c68d5fd51357e28f0742171e9161e9b/rails_generators
as for adding rake tasks ... i have yet to figure out howto do that :/
for now, i'm having my generators add require 'myproject/rails/tasks' (or something) to the project's Rakefile as a way to add rake tasks to rails from a gem.
a lot of gems ask you to 'bootstrap' them into your rails project, eg.
sudo gem install cucumber
cd rails_app
./script/generate cucumber # bootstrap cucumber into your app