In my previous post, Ruby Version Manager (RVM) Overview for Rails Newbs, I outline RVM’s architecture and fundamental features. That post is also very focused on RVMs role when running
Today, I’d like to cover a few more common scenarios Rails developers will encounter after the initial install of RVM. More to the point though, we’ll be focused on how RVM can be used to optimize workflow in these scenarios.
1. USE A DISTINCT GEMSET FOR EACH PROJECT
In my own development journey, it wasn’t initially clear to me when I should be creating new gemsets. If you too have pondered this question, here’s my suggested answer…create a new gemset for every project you are working on. This approach is not only clean and orderly but more importantly reduces the chance that gem dependency errors sidetrack your work.
As a refresher, here’s the necessary commands to create and use a new gemset:
$ rvm gemset create new_gemset_name
$ rvm gemset use new_gemset_name
Hopefully you’re starting to get some clarity on the use-cases for global, default, and custom gemsets. Basically, global and default are largely used to influence what you get from
rails new. Custom gemsets are then used to manage all gems related to a project from that point forward.
2. AUTOMATICALLY CHANGE RUBY VERSION AND RUBY GEMSETS WHEN MOVING BETWEEN PROJECTS
Like all devs, I’ve got lots of active projects in various stages on maturity on my machine. Before I came across this little nugget of knowledge (just keep reading!), I was frequently running:
$ rvm use ruby_version_here
$ rvm gemset use gemset_name_here
It worked pretty well, but when moving between projects in my command line I often got gem-related errors when trying to run
rails s or
rails c. The problem was that if I forgot to tell RVM to change gemsets when I moved across projects in my command line, the gems that project expected to be available weren’t there.
Before I get to the solution here, humor me with a quick aside…
In a previous life, I was an Excel junky. I really loved Excel and what it could do. Just like development, it offers an incredible combination of logic and creativity. Also like development, the mouse is not necessarily your friend. Learning to do things without leaving the keyboard can be a HUGE time saver. People who were more mouse-dependent would sometimes look over my shoulder as I worked and say, “dude, you need to teach a class on Excel!”. It was a nice compliment and while I was interested in sharing both my love of Excel as well as its features, I would often respond with,
“if you are ever working in Excel and thinking ‘there has to be a better way to do this’. There is. You just need to figure it out.”
The point is that even though I espoused awareness of this phenomena in the context of Excel, I lamely continued with my error-prone use of RVM for some weeks. It wasn’t until my good friend @megharastogi noticed what I was doing and said, “why don’t you use an
.rvmrc file sits at the root level of your application and basically tells RVM which Ruby version and gemset to use. RVM is smart and interprets these files as you navigate project folders in the command line.
Below is an actual
.rvmrc file in one of my apps. It’s stored at your_project_name/.rvmrc or in the below case social-playlist/.rvmrc.
Your .rvmrc file should be in the same location as your .gitignore, Gemfile, and README.
Boom! No more gem-related errors. Time saved. Happy dev.
3. CREATE AND USE A NEW GEMSET WHEN RUNNING
If you haven’t yet, at some point you’ll clone an existing repo. After doing so, likely your first task is to ensure you can get the app running locally in your development environment. For a Rails app, having the required gems present locally is a critical step in the process.
While you’ve cloned the repo, the repo likely doesn’t contain the actual gems. It merely contains a statement of what gems are necessary, via the Gemfile.
Here’s my recommended order of operations:
1. Review the repo’s README file.
2. Check the Gemfile of the target repo to see if a Ruby version and or gemset name is explicitly stated. (If it’s a Rails app, a Rails version will surely be stated).
3. Check the target repo for a .rvmrc file at project_directory/.rvmrc. If yes, this often also tell you which version of Ruby as well as the gemset name being used.
NOTE: As per the Typical RVM Project Workflow, other potential locations where Ruby version and/or gemset dependencies may be stated include files named: .versions.conf, .ruby-version.
4. If a Ruby version is explicitly stated, ensure that Ruby version is installed locally on your machine with
$ rvm list
a. If that version is already installed locally on your machine, make it active with
$ rvm use ruby_version_here and go to step 5.
b. If that version is not installed locally on your machine, get it with
$ rvm install ruby_version_name c. If no version of Ruby is explicity stated, I recommend using the latest stable version.
d. Make the target version of Ruby active with make it active with
$ rvm use ruby_version_here
$ git clone target_repo_location_here
$ git clone email@example.com:lostincode/social-playlist.gitor
$ git clone https://github.com/lostincode/social-playlist.git
Note: Both of the above commands clone the same repo, they just use different security protocols. For the truly adventurous reader, here’s a deep dive on the hows and whys of each protocol.
$ cd newly_created_directory_name
$ rvm gemset create new_gemset_name
Note: If the repo already contained a .rvmrc file with a gemset name, consider naming your local gemset the same as what’s being used by the other dev(s) pushing to the repo.
$ rvm gemset use new_gemset_name
$ bundle install
If no .rvmrc file is already present in the app, create one! It’s up to you if you include the .rvmrc in the .gitignore (I strongly suggest you do not! This as an important file for ensuring consistency across collaborators).
While not RVM specific, for good measure I’ll also offer up the other following steps to get the newly cloned app running locally.
$ rake db:create
$ rake db:migrate
$ rake db:seed (optional – only run if seeds.rb contains seed data).
Unless there’s database or server specific requirements, that should suffice to get the app running locally with
Looping back to the big picture before closing out on this topic. Now we have a distinct gemset just for this project (meeting the objectives of best practice #1) – and automated instructions for RVM to use this gemset whenever this project is active (meeting the objectives of best practice #2) in the command line. And we can be confident we are mirroring the Ruby and Ruby gem configuration of the other devs on the project.
4. CREATE A “RAILS 4 SCAFFOLD APP” FOR QUICK REFERENCE
In my other post, Reading Rails 4: MVC and Scaffolding for Rails Newbs, I go deep on some of the code generated when running
rails generate scaffold.
My original title and concept for the post was not Rails-version specific. I thought it would mostly be about MVC and scaffolding – but be agnostic of Rails version. However, by reviewing the output of rails new and rails scaffold (while having RVM use Rails 4), I quickly and easily learned a lot about Rails 4 versus the Rails 3 versions I was more familiar with.
The point here is that RVM (combined with rails generators), is your assistant in having multiple boilerplate/clean versions of working Rails apps side-by-side on your machine. This makes it easy to access, evaluate, compare, and understand fundamental changes in Rails versions. Personally, I found reviewing the output of a Rails 4 scaffold more educational on mass-assignment in Rails 4 than any online documentation.
If helpful, here’s specifically what I’m suggesting. Say you’ve been hesitating getting onto the Rails 4 bandwagon because you are up and running and proficient in Rails 3. Maybe you feel too busy right now to slow down and learn the “gotchas” in Rails 4. Well, I think 5 minutes spent on the following will probably get you past that hurdle
- Create a new gemset called “rails4scaffold” with
$ rvm gemset create rails4scaffold
- Make the new gemset active with
$ rvm gemset use rails4scaffold
- Install Rails 4 in that gemset by running
$ gem install rails 4
- Create a new app by running
$ rails new rails4scaffoldapp
- Scaffold a basic MVC in that app with rails generate scaffold books title author
Run rake db:migrate
- Now go inspect key files like app/controllers/books_controller.rb and run
$ rake routesto see how Rails 4 handles basic CRUD.
If you haven’t yet, consider moving Rails 4 into your default gemset!
As always, I really appreciate you reading my post. I hope it’s been useful for you in getting more value out of RVM. Your comments and feedback are welcomed.
One other quick point is that there are other tools and approaches for doing what RVM does (quite well in my opinion). However my goal is not to promote RVM, but to promote knowledgeable, confident, and satisfying development experiences. As such, I want to share a post titled “Vendor Everything” Still Applies by Ryan McGreary. In it, he makes some interesting and compelling arguments for an alternative approach to gemsets and gem management.
I’m personally still using RVM, but that doesn’t mean I will forever.
Truth fears no questions.
Reading between the lines of Mr McGreary’s post as well as some of the comments, I think the main point is that consistency in approach to gemset management within a collaborating group is critical to developer happiness and productivity.
Here’s some of my other posts you might like:
- Easy Does IT: Top 10 Gems for Rails Newbs
- Security is a Feature: Newb-Friendly Steps to Security Your Rails App
- Embedding Devise Forms in Twitter Bootstrap Modals