Build a Plugin or Gem? - ruby-on-rails

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

Related

Gem Vs Plugin Vs Engine in Ruby on Rails

What is the difference between Gem package, plugin, and Engine in Ruby on Rails?
I think we use the plugin before Rails3.2 and after rails3.2 is released we are using the gem package as a plugin but how can we use the engine in ROR?
Plugins as you knew them from Rails 2 (i.e. plugins under the vendor/plugins folder) were deprecated for Rails 3.2; support for it was completely removed in Rails 4. Now, there's a concept of a "gamified plugin" where the plugins are essentially built as gems and can be shared across different Rails applications.
But to answer your question about gems vs plugins, check out this Stackoverflow answer. Long story short, plugins from the Rails 2 universe is an extension of the rails application, whereas a gem is a packaged ruby application.
As for Rails engines, I've found this to be a pretty easy and intuitive definition of a Rails engine:
Rails Engines is basically a whole Rails app that lives in the container of another one. Put another way, as the docs note: an app itself is basically just an engine at the root level. Over the years, we’ve seen sen engines as parts of gems such as devise or rails_admin. These examples show the power of engines by providing a large set of relatively self-contained functionality “mounted” into an app.
And since both rails engines and plugins are types of ruby applications, they can all technically be packaged and used as a gem (usually).
There are no more plugins since Rails 4. Rails 4.0 release notes:
Rails::Plugin has gone. Instead of adding plugins to vendor/plugins
use gems or bundlers with path or git dependencies.
Any engine can be contained in a gem. Gem is just an alias to a 'library'.
Best way to see what their difference is is by generating three of them and looking through their directory structure:
bundle gem a_gem, used for non-rails-specific functionality.
rails plugin new b_railtie, used for rails extensions that don't require a full application-like setup. but, since it's still a rails-specific setup (you get your Rails dummy app in /test eg), you are probably going to use railtie in it. railtie is a class that inherits from Rails::Railtie, and gives you the comfortable DSL to hook up your code into Rails. eg, if you want some action performed :before some Rails app initialization step, you can use initializer Railtie class_method. Paperclip
rails plugin new c_engine --full, use for rails extensions that will be full-fledged app themselves, mounted into your app. will give you /app dir and Engine subclass besides basic non---full setup.
rails plugin new c_engine --mountable, same as --full, but will create namespaces, ready to be mounted into your app engine. Spree
And here is a pretty good link: http://hawkins.io/2012/03/defining_plugins_gems_railties_and_engines.
Engines are very related to plugins. Engines can be plugins and plugins can be engines. All of them can be created using rails plugin generator with 2 different options --full or --mountable.
I think the main difference here is between Engines and Gems.
Gems is just a bit of code providing a set of functionalities to anyone who integrates it into its code.
It contains:
Gemspec
Lib folder
Can be packaged and pushed to RubyGems servers
Engines are actually gems. All engines can be gems (if packaged) but not all gems are engines.
We can say it with a different word, Engines is a Ruby on Rails feature, that can contain Rails-specific entities: models, controllers, views, and migrations.
It needs to be integrated inside Rails application and can't run on its own.
Very good and quick read Artricle

What is the use of Gemfile in rails?

What is the use of Gemfile in rails?
How to use Gemfile?
During your development in Rails, there will be times where you will want to provide some functionality which is required by you, but either you don't know how to do or you don't want to implement it on your own since a lot of work has been put into its development by talented developers.
These developments which you might need (user authentication, message system, asset handlers, geolocation, pagination system, linking to exterior services such as Amazon AWS, and last but not least Rails itself) are called Ruby Gems. These are ruby software packages, not necessarily relating to Rails, but since Rails is based on Ruby, 98% of the gems can be made availble to your Rails webapp code.
Lots of gems can be found in github, but its funner to search for gems via ruby-gems or ruby-toolbox
Your gemfile is a list of all gems that you want to include in the project.
It is used with bundler (also a gem) to install, update, remove and otherwise manage your used gems.
The gemfile has another purpose - you can group gems in :development, :test, :assets, :production, etc groups and Rails will know when to include the gems. For example:
group :development, :test do
gem "rspec-rails"
gem "factory_girl_rails"
gem "guard-rspec"
end
Note that on Rails 4, the assets group has been deprecated
These gems belong to development environment and the test environment since they are for testing the application. You don't need them available in the production environment (you could, but that will bloat the memory unnecessarily).
So - To use the gemfile, simply write the gem you wish to install such as
gem 'devise'
make sure to install bundler beforehand (in your console/cmd/ssh) with
$ gem install bundler
and then write in the console
bundle install
you will notice another gemfile appears! Gemfile.lock
This file, as you will see if you open it with a text reader, lists all your gems with their version and their dependencies. This will come useful when you need to know which versions of the gems you installed.
For more reading on the Gemfile - read on the bundler page
for information regarding picking a gem you could start with this
Good luck and have fun!
Ok, so whats this Gemfile.lock that got created?
Gemfile.lock, as the name suggests is a locking on all the versions of all the gems that got installed. So if Gemfile is what required to be installed, the lock file is what got installed and what version are actually required to get the app up and running.
If you don't have the gems in that specific version (as specified in Gemfile.lock) rails will complain and you will have to either install the missing gems (via bundle install) or fix any conflicts manually (I believe bundler will give you some clues on that)
Some things to know about Gemfile.lock
if you accidently delete it, it will get regenerated when you run bundle install. If you accidently delete Gemfile, you are out of luck.. You should use git :)
Heroku doesn't care about Gemfile.lock since it will reinstall all gems. So for Heroku, you must set the gem version you want, or Heroku will always install the latest version of gem, which may cause issues
Keep the Gemfile.lock in your project so you will always know what version of gems make your app work properly.
Gemfiles are configuration for Bundler, which is used to manage your application's Ruby dependencies. That website includes a lot of documentation, including the Gemfile manual page.
Explanation by analogy
You want to build a car. From scratch. You need to build: a chasis, engine, corroborator, radiator etc.
Gems allow you to utilise car parts which other people have made before
Everyone's who's ever built a car has needed the same things.
You needn't reinvent the wheel. Why make your own engine etc when you can get it straight off the shelf? What if you could get one of the best engines around, created by the most talented engineers in the world, without lifting a finger? Are you gonna spend a year trying to make your own?
So basically rather than make everything yourself, you write down a shopping list of all the parts you need:
Rolls Royce Engine
AutoLive seatbelts
Michellin tyres.
PIAA Night headlights
etc etc.
That my friend, is basically your gem file!
Your system can have lots of gems ... thus can have multiple versions of same gem.
A Gemfile specifies the list of gems with their versions that shall be used/loaded/(install if not present) whenever you run your rails application. or anything with bundle exec . .
Firstly, what is a gem?
According to Wikipedia:
RubyGems is a package manager for the Ruby programming language that
provides a standard format for distributing Ruby programs and
libraries
Gemfile
A Gemfile is a file we create which is used for describing gem
dependencies for Ruby programs
Now, in very very simple words:
Gem can be thought of as a library which you can use in your code.
Example: faker gem
Your code can use the functionality of faker gem to produce fake data.
Now you can list all the gems that your project requires in the gemfile.
When you do a bundle install, all the gems in your gemfile are installed for you.

Rails: List of Gems being used by a particular application

There are many gems installed our development machines, and we not sure which gems are actually being used by the application. This list is not maintained in environment.rb either. Is there a way to figure our which gems are being used by a particular application?
[EDIT]:
Is it a safe way to find require in all .rb files and check in search result which gems are used in application?
Thanks,
Imran
You could try the standard rake tasks rake gems (should list the gems that this rails application depends on) or rake gems:unpack (should unpack all required gems into vendor/gems).
Not that I'm aware of, this is a motivator for folks to use bundler and rvm as this can be very painful if you've adopted a project that someone else wrote.

What's the difference between gems and plugins?

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.

Gem or Plugin , what is good for a ruby on rails project

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).

Resources