Ruby on Rails Best Practices and Tips by Toptal Developers

This resource contains a collection of Ruby on Rails best practices and Ruby on Rails tips provided by our Toptal network members. As such, this page will be updated on a regular basis to include additional information and cover emerging Ruby on Rails techniques. This is a community driven project, so you are encouraged to contribute as well, and we are counting on your feedback.

The idea behind the Ruby on Rails framework is to reduce time and effort required to build a web application. The downside is a burden on the developers and required knowledge of the framework, especially due to the convention-over-configuration nature of the framework. To ease this problem, our top Ruby on Rails developers and engineers will share here their best tips and practices.

Check out the Toptal resource pages for additional information on common Ruby on Rails mistakes, a Ruby on Rails hiring guide, Ruby on Rails job description, and Ruby on Rails interview questions.

How to Resolve Stuck ‘localhost’?

Have you ever found yourself in a situation when http://localhost:3000/ just won’t send requests to your development Rails server? I certainly have.

Here are a couple of steps to try out, before you start ripping your hairs out.

First, check that your Rails server is running:

ps ax | grep rails

Is Rails server running?

Next, check that nothing else is listening on the same port as your development server:

sudo lsof -iTCP -sTCP:LISTEN -n -P

What is listening on the same port as our development server?

By default, local Ruby on Rails servers listen to the port 3000. If this port is taken on your machine, or you want to run multiple Rails servers at the same time, pass -p <port> option with a port number you have available:

rails s -p 8080

Take into account that ports below 1024 are reserved for the system and require root access. So, for web server purposes, the most commonly used ports are between 1024 and 10000. Port 8080 is a good (and often used) choice because it is similar to the port 80, most commonly used for the HTTP requests.

If you are running a Rails server mapped to the domain name, you want to make sure /etc/hosts file is setup correctly. First of all, if you have edited this file before, make sure you do not mess up any of the default values. Below is the default /etc/hosts for OS X, which, among other things, contains localhost mappings for IPv4 and IPv6 protocols.

##
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
fe80::1%lo0 localhost

At the end of the file, add your dev domain mappings.

Different web servers such as Thin, Webrick or Puma bind to the localhost in a slightly different way, so it makes sense to specify both IPv4 and IPv6 mappings.

127.0.0.1 railsapp.dev
::1 railsapp.dev

Contributors

Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

How to Quickly Troubleshoot FactoryGirl Factories?

Let’s say you are using FactoryGirl and you have run into some kind of a problem with it. You are lost and wondering what the quickest way to troubleshoot the problem is. Where to even start? Luckily for you, Toptal’s best Ruby on Rails developers are here to help provide you a hint and a path to solution. Let’s start then.

First, you need to try FactoryGirl in Rails console. Run your Rails console in test environment with --sandbox option:

$ RAILS_ENV=test rails c --sandbox

If you have Rails 4 and above, use the following command:

$ rails c -e test --sandbox 
Loading test environment in sandbox (Rails 4.2.1)
Any modifications you make will be rolled back on exit

As you can see from the welcome message above, --sandbox option will roll all database changes back after you close the console. You didn’t intend to leave all the test data in the database created by your factories, did you?

After that, you need to require factory_girl_rails, if it isn’t required automatically, in your test environment:

require 'factory_girl_rails'
# => true

Now you can create your models via FactoryGirl:

user = FactoryGirl.create(:user)
# lots of sql here
=> #<User:0x007fe143a0c7e8
 id: 13,
 email: "paolo.lebsack@mayertstamm.biz",
 encrypted_password: "some password over here",
 reset_password_token: nil,
 reset_password_sent_at: nil,
 remember_created_at: nil,
 sign_in_count: 0,
 current_sign_in_at: nil,
 last_sign_in_at: nil,
 current_sign_in_ip: nil,
 last_sign_in_ip: nil,
 created_at: Fri, 13 Nov 2015 16:06:20 UTC +00:00,
 updated_at: Fri, 13 Nov 2015 16:06:20 UTC +00:00,
 state: "UT",
 name: "Karli Erdman Sr.",
 authentication_token: "and maybe even some token",
 balance: 0,
 free_entries: 5,
 phone_number: nil>

If everything went smoothly, you should see in your SQL log all models have been saved correctly, and you will get your fresh user as a result from FactoryGirl. In case there is a problem, you’ll hopefully get an error message, or you’ll be able to understand more about your problem from the SQL log and what went wrong.

Contributors

  • Small dd10b27a57f198945e4d2f82e86629adAlexey SheinTashkent, UzbekistanView Alexey
Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

How to Run Rubymine Scratch File in Rails Environment?

Say you want to run scratch file in a Rails environment, but couldn’t seem to find a way to do it. Luckily for you, a Toptal Ruby developer created a step-by-step guide on how to run Rubymine scratch file in Rails environment:

1) Create a scratch file (Double Shift to run Search Everywhere, then write New Scratch, and press Enter), or ⌘⌃N if you use Mac

2) Put some code in it to test if the Rails environment is really loaded, for example

puts User.count

3) Then create “External Tool” (that’s RubyMine’s term for user-defined shell command that can take any file as an argument) to run any currently opened file (it doesn’t necessarily need to be a scratch file, it can be any file) by hotkey.

For that, you need to create some “rails”-executable wrapper that you can run from RubyMine. Rails 4.2 comes with spring gem that can generate “rails”-executable wrapper (binstub in Spring terminology) for you. Just run

spring binstub rails

or

spring binstub --all

and Spring will generate all necessary binstubs and place them in bin directory of your project. Generated binstub will be spring-ified, which means that all consecutive script runs will be much faster and won’t require loading Rails from scratch every time. This is exactly what you need. Don’t forget to commit generated binstubs into repository.

4) Create “External Tool” to run your scratch file with Rails Runner. For this, open Preferences -> Tools -> External Tools -> Click on Plus icon and create your very own Rails runner external tool as shown in the screenshot: If you use RVM, then you need to wrap your binstub with rvm so it would know what Ruby to use, see the following screenshot:

5) Now create a new hotkey so you can run your file with a single push on the button (well, actually, two buttons). Open Preferences -> Keymap -> and find your external tool (you can filter it by its name) or just going directly to External Tools -> External Tools. Assign some hotkey for it (click on the item with the right mouse button and choose Add Keyboard Shortcut), usually ⌥ + some-letter bindings are free (as in speech), for example, I use ⌥S. You should get something similar to this:

6) That’s it. Now open your scratch file and run ⌥S. If you have done everything correctly, your scratch file will be run inside the environment of your Rails project.

Contributors

  • Small dd10b27a57f198945e4d2f82e86629adAlexey SheinTashkent, UzbekistanView Alexey
Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

How to Install 'Capybara-Webkit' on Mac OS X Yosemite

One of the Toptal developers has recently run into a problem when he needed to install a capybare-webkit on a Mac OS X.

There were also problems when Mac OS X Mavericks came out. The solution back then was to replace built-in compiler from clang to gcc/g++. This was simple - with brew you would just install gccand put the following lines into your .dotfiles:

# Because of Maverick...
#export CC=/usr/local/bin/gcc-4.2
#export CXX=/usr/local/bin/g++-4.2

These two compilers served our developer well over the last year. Until the new Mac OS X was released, the Yosemite release. After the update, the compiler started throwing the following errors:

g++ -pipe -O2 -arch x86_64 -Xarch_x86_64 -mmacosx-version-min=10.5 -Wall -W -DQT_NO_DEBUG
DQT_WEBKIT_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED 
I/usr/local/Cellar/qt/4.8.7/mkspecs/macx-g++ -I.
I/usr/local/Cellar/qt/4.8.7/lib/QtCore.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtCore.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtNetwork.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtNetwork.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtGui.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtGui.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtWebKit.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtWebKit.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/include -Ibuild -F/usr/local/Cellar/qt/4.8.7/lib -x c++-header
c stable.h -o build/webkit_server.gch/c++ gcc -pipe -O2 -arch x86_64 -Xarch_x86_64 
mmacosx-version-min=10.5 -Wall -W -DQT_NO_DEBUG -DQT_WEBKIT_LIB -DQT_GUI_LIB 
DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Cellar/qt/4.8.7/mkspecs/macx-g++ -I. 
I/usr/local/Cellar/qt/4.8.7/lib/QtCore.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtCore.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtNetwork.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtNetwork.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtGui.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtGui.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtWebKit.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/lib/QtWebKit.framework/Versions/4/Headers 
I/usr/local/Cellar/qt/4.8.7/include -Ibuild -F/usr/local/Cellar/qt/4.8.7/lib -x objective
c++-header -c stable.h -o build/webkit_server.gch/objective-c++ In file included from
/System/Library/Frameworks/CoreServices.framework/Headers/CoreServices.h:55, from
/System/Library/Frameworks/Foundation.framework/Headers/NSURLError.h:12, from
/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:80, from
/System/Library/Frameworks/Cocoa.framework/Headers/Cocoa.h:12, from
/usr/local/Cellar/qt/4.8.7/include/QtGui/qmacdefines_mac.h:113, from
/usr/local/Cellar/qt/4.8.7/include/QtGui/qwindowdefs.h:99, from
/usr/local/Cellar/qt/4.8.7/lib/QtGui.framework/Versions/4/Headers/qapplication.h:46, from
/usr/local/Cellar/qt/4.8.7/lib/QtGui.framework/Versions/4/Headers/QApplication:1, from
stable.h:1:
/System/Library/Frameworks/CoreServices.framework/Frameworks/FSEvents.framework/Headers/FSEvents.h:262: error: expected `}' before ‘__attribute__’
/System/Library/Frameworks/CoreServices.framework/Frameworks/FSEvents.framework/Headers/FSEvents.h:262: error: expected unqualified-id before ‘=’ token
/System/Library/Frameworks/CoreServices.framework/Frameworks/FSEvents.framework/Headers/FSEvents.h:414: error: expected `}' before ‘__attribute__’
/System/Library/Frameworks/CoreServices.framework/Frameworks/FSEvents.framework/Headers/FSEvents.h:414: error: expected unqualified-id before ‘=’ token
/System/Library/Frameworks/CoreServices.framework/Frameworks/FSEvents.framework/Headers/FSEvents.h:493: error: expected declaration before ‘}’ token make[1]:
*** [build/webkit_server.gch/objective-c++] Error 1 make: *** [sub-src-webkit_server-pro-make_default-ordered] Error 2 Command 'make' failed

Unfortunately, he couldn’t replace capybara-webkit with poltergeist, so he had no choice but to somehow find a way to install capybara-webkit on his new operating system update.

Both capybara-webkit and poltergeist serve the Ruby on Rails community as very useful tools for end-to-end testing of the JavaScript heavy web applications. They both play an important role in the Ruby on Rails ecosystem.

Anyway, after some googling and spending a lot of time at the Stack overflow, a fellow Toptal Ruby on Rails developers finally helped him.

The problem was that he was using gcc compiler instead of cland compiler, because gcc compiler doesn’t recognize the Objective-C extended headers. The solution in the end was again very simple, he just needed to change gcc/g++ to clang in his .dotfiles:

export CC=clang
export CXX=clang++

After that change, capybara-webkit finally compiled successfully. The lesson he learned is that a bad solution brings another problem into the field. We hope you will also learn something new from his experience.

Contributors

  • Small a0c7d00451a53a8184c6e06de075d085Orban BotondGheorgheni, RomaniaView Orban
Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

How to Setup Back-End Development Environment as a Front-End Developer?

Say you are a front-end developer and you join a project that uses Ruby on Rails on the back-end. The only problem is that you work on a Windows machine, and setting up the Rails project is making you tear your hair out. At every step, it seems like there are weird PATH issues and other bewildering incompatibilities, and you end up sinking days into the setup before you can even get started coding.

There are countless variations of this scenario, which comes down to working on a machine that is ill-suited to your project’s stack. But what else can you do that doesn’t involve going permanently bald?

Toptal developers recommend making use of virtualization software like Vagrant. Vagrant is more than just a virtual machine. It’s a management tool that allows entire development environments to be set up and run quickly and easily. Vagrant allows you to choose from VirtualBox, VMWare, and many other virtualizers. It lets you to select your OS, environment variables, tools that will be installed, and even provides a fully transparent window into the VM for your favorite IDE or browser, so you can test your code just like it was running on localhost. And the whole thing can be set up and run with a single config file and one command in the terminal.

So next time you find yourself facing a project you don’t have the right machine for, save that awesome hairdo and fire up a virtual environment that is perfectly suited to your needs.

Contributors

  • Small 0a47fcca 4d52 48c0 a049 0eb9ec26031aJason LewisBroomfield, United StatesView Jason
Like what you're reading?
Get the latest updates first.
No spam. Just great engineering and design posts.
Like what you're reading?
Get the latest updates first.
Thank you for subscribing!
You can edit your subscription preferences here.

What Are the Pros and Cons of Creative Naming of Test Variables and Data?

A subtle issue that comes up occasionally when writing tests revolves around the question of naming: is it preferable to use creative names for test data, such as Wayne Enterprises, or to use dry and boring names like Company 1?

This of course depends on the developer and on the project, but several interesting points come up when examining this question closely.

Many Toptal developers find that tests are easier to read and understand when they use creative naming schemes. The relationships are more naturally apparent. It also makes working with the specs more interesting and less of a drag. This can bring many indirect benefits to the team, helping keep everyone engaged and having fun.

However, it is easy to get distracted when coming up with creative names, leading to reduced productivity, and even resulting in more confusing specs that try to be too “clever”. To keep distractions in check, some Toptal developers restrict their source of names to a limited group of existing works of fiction - for example, Batman, Futurama, and Star Wars.

Another important consideration is that test data must clearly model the relationships you are trying to test for. With creative test names, it can be easy for the test data to suggest relationships that don’t actually exist in the data. Are Mario and Luigi siblings or just two users? Additionally, if it is not very clear that a variable name comes from popular culture, it may confuse another coder who doesn’t know the reference. We can expect most developers to recognize that Chewbacca is just dummy data, but Luke might be someone you work with, and Millard Fillmore might not be a name that your colleague in another country recognizes.

It may seem like a minor issue, but keeping work interesting, fun, and easy is very important. If you know your teammates very well, creative test data can actually help keep things moving. But if you are not that familiar with everyone who may be looking at your tests, keeping names more dry and sanitary may be a safer policy.

Contributors

  • Small img 5429Carl DunhamProvidence, United StatesView Carl
  • Small ebf9c08d 239d 4413 927a 91c5c8d10cd5Dave AronsonFairfax, VA, United StatesView Dave
  • Small 618470b1 b4b7 45d0 9b6f 542bd42e1b3bBranislav HaštoLiberec, Czech RepublicView Branislav

Submit a tip

Fields marked with an asterisk (*) are required
Thanks for submitting your tip proposal
Our editorial staff will review it shortly. Please note that tips proposals are subject to review and editing, and may or may not be selected for posting, at the sole discretion of Toptal, LLC.