#384 Exploring RubyGems
RubyGems make it easy to add features to Rails applications but they can also cause headaches. How should we decide whether to use a gem or writing something from scratch? If we do decide to use a gem how should we decide which one to use when there are many available that seem to accomplish similar tasks?
This episode will be a little different: we’ll give you tips on exploring gems and finding the one that’s the best fit for your need. One of the first places to turn to is The Ruby Toolbox. This breaks projects down into categories so it’s a great way to see which gems are the most popular for, say, authentication.
At this point it’s a good idea to narrow down our application’s requirements. If we want to add authentication we need to ask ourselves if we want to authenticate through third-party providers such a Facebook or Twitter or handle authentication through user accounts and passwords. If it’s the latter do we want the ability to reset passwords and do we care what the authentication looks like? All of these are great questions and can help us to decide which gem to use as each handle authentication in their own unique way.
Another important factor in deciding is seeing how active each project is. The Ruby Toolbox gives us some idea but it’s a good idea to check any potential gem’s Github repository to get a more accurate description. We’ll focus on the Devise gem which is one of the most popular Rails-related gems. Its Github repository shows that it’s regularly updated which is a good point in its favour. If there had been only a few commits over the last year or so then we’d probably be better off looking elsewhere as it might not work with the current version of Rails or might break when the next version is released. It’s also worth checking the project’s issue tracker. Comparing the number of open issues with the number of closed ones gives us a good idea on how responsive the gem’s developers are. Devise has over 2,000 closed issues which suggests that its contributors work hard to fix any problems.
Next we’ll look for the project on RubyGems and compare when the different versions of the gems were released. The most recent release of Devise was back in June 2012. This could mean that it was a really solid and stable release but it’s worth bearing in mind that this will always be behind the Github repository. While we’re checking this we’ll also take a look at the gem’s runtime dependencies. It’s important to understand that we often not just adding a single gem to our application but also its dependencies and sometimes these dependencies have their own dependencies so we could be actually adding quite a number of gems and these are all components that could break compatibility in an update. When we run into an issue with a gem where it doesn’t behave like we’d expect it to this is often caused by a dependency issue.
This is why the Gemfile.lock
file in our Rails applications is so critical. It locks down all the versions of each gem and its dependencies so that even if a new version of one of the gems is released it will stick with the current version until we run bundle update. We should watch out for odd issues when we do run this command as there may be incompatibilities. Also, when we add a gem to a gemfile we should think about using the tilde (~
) operator to specify the version number so that if there is a major update and we run bundle update
it will only update to a version that only differs by the last part of the version number and this should always be backwards compatible with the version we installed.
Documentation
Next we’ll talk about documentation. This is sadly lacking in many Ruby gems but sometimes a gem is well documented if you know where to look. It’s always a good idea to take a look at a project’s wiki as there can be a goldmine of information there that is easy to miss. Sometimes not all the pages in the wiki are linked so it’s best to click the “Pages” tab for a full list. We should also take a look at the RDocs which can often be found at RubyDoc.info. This provides a nice way to browse the documentation that’s within the project’s source code. We can often find all kinds of good information here and even if there isn’t extensive documentation we can find a good overview of the different classes and methods that the gem includes.
Another great way to learn about a project is to dive into the source code itself. Not only will doing this give us a better understanding of the gem we might learn some interesting tricks, too. We can browse the source on Github or, for a better look, clone the repository and browse it locally. Let’s do this with the Devise source code. We can clone the repository by running this command.
$ git clone https://github.com/plataformatec/devise.git
One way to estimate the size of a project is to do a line count. The
$ cloc app lib 87 text files. 86 unique files. 23 files ignored. http://cloc.sourceforge.net v 1.56 T=1.0 s (64.0 files/s, 5294.0 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Ruby 64 762 1513 3019 ------------------------------------------------------------------------------- SUM: 64 762 1513 3019 -------------------------------------------------------------------------------
This shows that the gem contains around 3,000 lines of Ruby code which is rather a lot. Devise is definitely one of the larger authentication libraries which may make you reconsider using it. That said, we also have to take into account the number of features that it offers and this is why it’s important to understand exactly what our requirements are before choosing a gem to use. If we want a more lightweight and simpler approach to authentication we could consider writing it from scratch, like we show in episode 250, and which can be done in around a hundred lines of code.
Another good thing to check is the number of lines of code in the spec
or test
directory. This gives us a rough idea as to how well the project is covered and it shows whether the gem is well tested or not.
$ cloc test 106 text files. 106 unique files. 14 files ignored. http://cloc.sourceforge.net v 1.56 T=0.5 s (186.0 files/s, 15204.0 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Ruby 88 1386 279 5837 HTML 3 3 3 72 YAML 2 2 5 15 ------------------------------------------------------------------------------- SUM: 93 1391 287 5924 -------------------------------------------------------------------------------
Devise has nearly 6,000 lines of code which means that it has twice as much test code as application code and suggests that the application is well covered by tests.
Next we’ll take a quick look at the gem’s source code. A good place to start is the lib
directory in the file whose name matches the gem as this is often the first file that’s loaded in. This file will often show us the gem’s dependencies and give us an overview of its structure. From there it’s worth taking a look at the railtie file if the gem has one. For Devise this file is at lib/devise/rails.rb
and it will give us an idea of what happens when this gem is loaded into a Rails application. This is a full-on Rails Engine which is why it has an app
directory so that it can load in other files for models and controllers and so on. This file also loads in some middleware for Warden also for OmniAuth. Getting to know what’s happening in this file can really help in debugging situations when things seems to go haywire.
If the gem is an engine we should take a look at its app
directory. There’ll be a lot of things that we’ll need to get to know fairly well as we might need to override certain behaviour and it helps to know what the gem is providing to our Rails app. We won’t be doing this here but it’s usually pretty easy to walk though as it’s basically a Rails app within a gem.