I work at a company where I develop on over 10 different ruby and rails apps. Between these ten apps, I have 3 ruby versions and 7 gemsets (total). There are certain utility gems (like pry, colored, git-up, hookup, etc.), which I would like to be able to install once (per ruby — if necessary) and have access to across gemsets within the same ruby versions.
I tried installing these gems into the 'global' gemset for each ruby version, however, once I cd into a project and the gemset changes (same ruby version though), I no longer have access to the gem's executable. I have to reinstall the gem in the specific gemset.
I just get the feeling that I am missing something as I have so many duplicate gems installed on my system. What are the best practices around this desired behavior? Can anyone point me in the right direction?
Thank you.
If you wanna install a gem per ruby, you need to do a gem install pry for instance. That will install the gem on the ruby level. After that you can require that in your Rails app, for instance on the boot.rb file.
I am not sure how rvm deals with gemsets. If what they do is change the entire folder reference of the gem command, then you wont be able to do that. I would need to install those gems for every gemset, which is a PITA.
On my workflow, I dont need gemsets, as I have bundler. So I use rbenv to install and change ruby versions, and let bundler deals with gems for a project. Like so, I can install a gem, globally per ruby, and it works.
Related
I would like to understand a very basic concept in Ruby on Rails. Everytime I create a new Rails application, I used to create a gemset and then install gems to that gemset. Once my friend asked me why I do that and I failed to make him understand very clearly.
Is it because if I have 2 projects under the same Ruby version and if both need different versions of a particular gem? Suppose, both are using the default gemset, it can't install both versions of this gem to the default gemset as it would cause a conflict? Please correct me if am wrong.
Gemsets are useful to make independent rails application, where other rails application (with the same ruby version) does not share gems among each other (as it does gem bundler)
For now, using of gemsets is overhead, because:
gemsets decreases download gem speed
gemsets increases space on a hard drive
gem bundler handles dependencies well
if your gems will be corrupted, you can restore them with gem pristine --all
development and production environments go towards Docker with its own independent layers
Just don't use gemsets
By gemset you mean RVM Gemsets right? RVM Gemset compartmentalized ruby setups, from the system and each other. This is very helpful if you have multiple Rails project for example. Each project might require different versions of same gem(s).
However, if you are using Bundler you don't need to use RVM Gemsets. Prepending any command with bundle exec will execute it in the context of the project's Gemfile.
References
Related question on Stack Overflow
How to use Bundler instead of RVM Gemsets
It's very interesting questin.
you can consider gemset is = kind of space in hard drive
I will show you full process.
if you have more then one projects with different ruby versions then we need to use rvm to avoid conflicts.
so for that we need to use RVM (Ruby version manager).
Steps:
1) install rvm
2) after installing rvm we need to use ruby version
ex : if you have more then one ruby installed in your system then chose one of them
rvm --default use version
For example you have 2 projects with ruby 1.9.X and other project with 2.0.X
So in this situation if you are not using rvm then it may chance to get conflicts so we should create new gemset like bellow.
Ex:
rvm gemset create demo
rvm gemset use demo
so currently we are pointing to gemset demo
now we already install ruby but we do not have rails in this gem so we must install rails and other gems in it.
so the conclusion is that we use gemset for avoid conflict between to ruby versions.
I'm using RVM and Gemsets to manage my Ruby project environments, I keep an .rvmrc file on each project directory in order to get a different Gemset (using rvm use --create 1.9.3#<project_name>). Everything works well in that manner, but:
For some reason though, when I use rvm use <ruby_version>#<gemset_name> and then gem list I get a mixture of the correct gems (the ones which indeed - have been installed in my project), as well as some other gems which are definitely not related.
Any idea what may causing this? maybe there's a 'default' gemset which if I accidentally installed some gems on it, It'll include them in all of my gemsets?
Thanks for the help
Never mind, found my answer in here - Interpreter global gemsets:
RVM provides (>= 0.1.8) a #global gemset per ruby interpreter.
Gems you install to the #global gemset for a given ruby are available to all other gemsets you create in association with that ruby.
This is a good way to allow all of your projects to share the same installed gem for a specific ruby interpreter installation.
I am following these instructions: https://github.com/phifty/agraph/blob/master/README.rdoc,
and there is a step to install a gem using this command:
gem install agraph
I am new to RoR, but I have RVM and Bundler. I am not sure which I should use. Should I install this using RVM or Bundler? What should be the command?
RVM is Ruby Version Manager. It lets you maintain separate installs of Ruby side-by-side without conflicts, easily. One of the requisites for doing this is keeping gems for each version of Ruby separate since the installers can "toggle" based on which version of Ruby you're running.
Gem is a command that lets you install gems. It's the core of the whole infrastructure – it doesn't call out to a lower-level "packager" to do its work.
Bundler runs "on top" of Gem. It makes managing gem versions easier, much like RVM does for Rubies (versions of Ruby). It'll automatically install gems that aren't installed, so you don't need to explicitly run gem install gem-name before running bundle (or bundle install).
Gem, Bundler, and RVM all cross paths if you start using RVM's gemsets. They allow you to further isolate and control your environment by creating a separate "gem environment" of sorts. The primary use for this is so that you can keep gems for different projects separate, which aids in managing versions. If you use Bundler, this isn't really as important or useful as in pre-Bundler days where Rails/Sinatra/etc. would require the most recent version of a gem.
Does that answer your question?
If you are using Rails 3 you should put the command in your application Gemfile
gem 'agraph'
then run bundle install. This will take care of dependency resolution and bundling the gem on your production servers when you deploy.
For RVM the only thing you might want to do is set an RVM gemset for your application. You can do this by creating a .rvmrc file in your application directory, which will automatically set the RVM ruby version and gemset when you enter into that directory. You should not manually install gems for your application using RVM.
Following current best practices, what is the proper role for each of these?
Based on my limited understanding of Bundler and RVM, it seems that they--like Rubygems--have their own install locations for gems. Plus, for each one, there's the option of installing to system paths using sudo or to your home directory. And then there's the ability to vendor gems with Bundler (where applicable, e.g. with Rails).
So it looks to me like there are at least seven places to install gems now:
Rubygems system path
Rubygems user path
RVM system path
RVM user path
Bundler system path
Bundler user path
Vendor (per-app)
So, what's the best way to manage all this? Do we use all three (Rubygems, Bundler, RVM) and tell them all to install gems to the same place? Do we use sudo all the time, some of the time, or never? And should we be using a different strategy on production and development machines?
On a related note, are Bundler and RVM wrappers around Rubygems, are they alternatives to it, or are they completely orthogonal to it?
From Bundler's website:
Bundler makes it easy to make sure that your application has the dependencies it needs to start up and run without errors.
This means that it's trivial for some other developer, or you on another machine, to get ready to develop further or use it, by running bundle install and you have everything you need to get up and running.
RVM is for managing multiple versions of Ruby on the same machine, and switching between them. Gemsets is a powerful feature RVM provides that isolates gems for one application/library from the rest of your system.
When using RVM and Bundler together, RVM tells Bundler where the gems should go, and Bundler installs them into the RVM-folder.
Both (with regards to gems in RVMs case) use and depend on Rubygems, so they're closest to wrappers.
I, personally, use Bundler and RVM for all my projects. No gemsets, just Bundler to resolve and fix things, which it does without fail. Installing gems is done without sudo, and ends up in the place RVM defines. The default Ruby install on my system is left alone, and nothing is installed to Rubygems system/user path
The way I do it now (still experimenting a bit though) is this:
Use RVM to set up the ruby version and a gemset to use for an app. I use an .rvmrc-file in the root of the app directory to make sure the correct ruby and gemset is used all the time.
Bundler is installed using gem without sudo in the given gemset.
Any gems needed by the app is added to the apps Gemfile and installed using Bundler. I'm not using sudo for this.
This way I use Bundler to keep track of the dependencies for each app, and RVM to isolate each app's gems from each other. Works really smooth, actually.
I have not yet installed RVM on my deployment server, there I just use Bundler to make sure each apps dependecies are handled. I will probably install RVM there as well, but have to figure out how that plays ball with Passenger first.
As for your last question, Bundler is a wrapper around gem, RVM just manipulates the gempath where gems are installed. It seems to be smart enough that it picks up the gems from the same place though so I don't need to recompile any that are already installed in some other gemset.
I've stopped using sudo for installing gems after starting to use RVM. There's really no reason over just installing them in the rvm user path. I'm unsure about the best practice if you have more developers on the same machine like a test server or something like that.
I want to switch between rails 2.3.10 as the "active" gem for my OS, so that I can invoke it at the command line.
Is it possible to do this? I'm not using rvm. Maybe it's time to start.
I tried gem install rails --version=2.3.10, but that just makes sure that version of the gem is installed, it doesn't put it in /usr/bin/rails.
(I do already use bundler for my apps -- but haven't needed any precise control over gems at the OS level until now)
If your problem is to run binaries of a certain version, then:
rails --version # => the latest version
rails _2.3.10_ --version # => Rails 2.3.10
This pattern (gem-binary _gem-version_) works for any gem binary.
Use RVM
RVM allows you to manage different versions of Ruby and Gems. You can install a version of ruby using, for example
rvm install 1.9.2
You can then use it using:
rvm use 1.9.2
Use specific gems on a per project basis with gemsets.
If you want further namespacing you can set up gemsets; directories which will contain specific gems for a specific project.
rvm gemset create myproject
then you can use them like so:
rvm use 1.9.2#myproject
Automation
To automate the process of switching gems, pop .ruby-version and .ruby-gemset files in your project root. Pop the version of Ruby and name of the gemset you want to use inside them and RVM wil select the correct gemset when you cd into your project directory.
Installing gems into your gemset
Install your gems into your gemset in the usual way using bundler if you are using it:
bundle install
or just using the regular old:
gem install mygem
The gems will go in the right gemset.
RVM Alternatives
You might also want to check out rbenv, which does similar job.
You can use RVM
Then you can also use Bundler afterwards, which manages gem dependencies fine.
In your Gemfile
gem "rails", "2.3.10"
and in your application
require 'rubygems'
require 'bundler/setup'
and you're done.
EDIT: Just saw your RVM mention in the post. Definitely the way to go.
You're going to want to install RVM -- it's an amazing package that will let you manage different Rubys and different sets of gems on the same machine. You can switch back and forth with total ease.
Here's the installation guide: http://rvm.beginrescueend.com/rvm/install/
Once you got everything get up, you can see all of your installed rubys at the command line with with rvm list, and switch with rvm use ruby-head, for example. RVM keeps the gems on each ruby separate, which should help with your question.