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.
Related
I know that if application uses bundler, I can easily find all the gems installed by looking at the Gemfile.
Say, I am looking at the Rails 3 application that doesn't use bundler, how do I know what gems it uses?
Thanks
If it's not using Bundler, I don't know of a definitive way to identify every gem being used. You could search the entire app tree for require statements to start with, but that's not going to show most of them. Gems also require other gems internally, and will install their own dependencies, but those gems won't be referenced directly from your app's require statements.
If the app works and the tests pass (meaning you've at least got all the required gems installed), you could approach the problem by creating a Gemfile, listing the gems you know are needed, and then running your tests (or the app itself) via bundle exec, which will ensure that only the gems listed in the Gemfile are visible. Then you'll get failures related to missing gems, and can add them to the Gemfile until it all works. Once it's working via bundle exec, you'll know that you've captured all the requirements there.
If you're using RVM, you'll probably find it helpful to create a gemset for your app, along with a .rvmrc file in the app root, to take advantage of RVM's automatic gemset switching and Bundler integration. It'll make it easier to maintain the gem state going forward.
In any case, running gem list with the app in a working state will show you all the gems that it might be using, but without being scoped to a gemset or wrapped in bundle exec, you'll also see gems that were installed for other reasons that potentially have nothing to do with your app's dependencies.
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.
Our project is Rails 2.2.2, maybe it can't use Bundler? (or maybe for some other reasons, Bundler cannot be used)
Then in that case, what is the most preferred way of freezing the gems into the project source tree?
Some that I know of are:
rake gems:freeze
needs gemsonrails and it doesn't work with the current gem 1.3.7
rake gems:unpack
will not freeze the depended gems. have to add it one by one manually
script/plugin install
need to install the depended gems one by one as well
you can unpack the gems into your vendor directory. once they are on the server just run rake gems:unpack and that will build them like how plugins are built or at least put into the file structure.
I've done this not for dependency and upgrade issues but for shared hosts, hosts without gem support, and actually to modify gems that need a one liner tweek.
we use rake gems:unpack and rake gems:unpack:dependencies.
My Rails app uses the TMail plugin, but it requires a modification to Attachment.rb.
The modification is recognized and loaded by Rails on my development machine, but in the production environment on my hosting provider (Rails Playground), the system version of TMail is loaded and not our custom version.
Online document about the best way to include or freeze gems is confusing on many sites.
Anyone have a definitive answer about the best way to approach this?
Thanks!
rake gems:unpack:dependencies
This will copy all gems you specified in environment.rb into vendor/gems
These will be used on the remote machine. If you modify them in the vendor directory I see no reason this should not be used as well.
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