Are you interviewing for a frontend developer or Ruby on Rails engineer position? In addition to these 11 questions, here are eight more interview questions you should know and be able to answer. They will prepare you for questions about Rails ActiveRecord, caching, database design and architecture, APIs and system monitoring, and logging.
Extended reading: 11 Ruby on Rails Interview Questions and Answers
id
matches one of the ids in this list [1, 5, 30]? Additionally, how would you show the average of the field total
?
#1 Given this model with a few fields, how would you select all model instances where the field This question can see if you have mastered the basics of Rails, such as whether or not you know how to query for models based on different filters and field values. The latter part of the question will show if you know how to go further and apply aggregation functions through the Rails ActiveRecord querying interface.
To answer the first part of this question, given an ActiveRecord model named "Product", you would do something like this:
Product.where(id: [1, 5, 30])
To answer the second part of the question, you would do something like this:
Product.where(id: [1, 5, 30]).average('total')
The interviewer may ask follow up questions, such as how to limit the number of results returned. This is important because you don't want to overload the database by returning millions of results. They may ask how to sort the results too. To learn how to do this, read and review the Rails Guide to Active Record Query Interface.
#2 There is a model with three fields, how would you add validation to them?
Like the last one, this question shows how much you know about the basics of Rails. Note that you would usually refer to the Rails documentation or other documentation to find out how to add specific types of validation. However, for an interview, you should be aware of what options are available and be able to recall the function and method names.
For example, the interviewer could ask you how you would ensure that the fields name
and email
are not empty for the "SurveyResponse" model, and you would write something like this:
class SurveyResponse < ApplicationRecord
validates :name, :email, presence: true
end
they could also ask you to ensure that a particular field is unique, which you would do so by doing something like this:
class Product < ApplicationRecord
validates :sku, uniqueness: true
end
The Rails Guide to Validation has more information on the validators and how to use them.
#3 We have a model that needs data sent to a 3rd party API service after it is saved to the database. What code we need to accomplish this?
The first thing to do is recognize that we are being asked to use callbacks. When an Active Record model is created, updated, saved, and committed to the database, any registered callbacks are called at those points in the lifecycle.
For this particular question, we would use the after_save
callback because it is called whenever the model is created or updated.
This is how the code could look like:
class MyModel
after_save :send_data_to_3rd_party_api
def send_data_to_3rd_party_api
end
end
The interviewer may also ask you about the before_validation
or after_commit
callback. For instance, they may ask, at what point in the lifecycle, you would invalidate the cache for a model. To answer that sort of question, you could use the after_commit
callback, as it is called after every create, update, or destroy that takes place.
You can find out more about the Rails Active Record lifecycle callbacks in this Rails Guide.
#4 How would you define a database migration that creates a new table for a model that includes timestamps and two fields: name and email address?
This is a slightly more advanced question but a typical task you will have to do when working on a Ruby on Rails web application. You will need to be able to create new Active Record models and their corresponding database tables.
The answer to this particular question is the following code:
class CreateMyModels < ActiveRecord::Migration[5.0]
def change
create_table :my_models do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
The timestamps method will add two columns to the table which are called created_at
and updated_at
. The string method will create a string field in the database with the given name as the column name.
Knowing how to create new models by using migrations and defining data tables is one of the necessities when working with Rails. You can review the guide for creating Rails migrations here.
#5 How would you log errors in Rails?
Errors and bugs in programs do occur and Rails is no different. When an interviewer asks you this question, they are wondering whether you know how to debug a program. To answer this question, you can start with this code:
Rails.logger.debug "This is an error"
Then you could talk about the different log levels: verbose, error, info, fatal.
The interviewer may then ask you about other tools for debugging a Rails app. To this, you can reply "byebug" which lets you set breakpoints and step through a Rails app.
The interviewer may show you a Rails controller or Active Record model, and ask you fix the bugs that exist within it, or to point out and log potential issues. Knowing how to add logging statements can show that you know how to handle debugging in a production environment.
Here are more ways to debug a Rails app.
#6 How would you design a shopping cart that contains a Cart model and Item classes? How would you define the association and database relationship?
It is very likely that an interviewer will ask you to design and implement a few models to understand how well you understand the basics of Rails. They also want to find out what sorts of questions you ask about the problem, such as if particular details need to be added to the models.
So let's use the example of a shopping cart design to see one way of answering this interview question.
One way to define the model is to have a Cart active record and an Item active record. The cart would have a has_many
association with the items, and the Item would have a has_one
relationship pointing back to the cart. You can find out more about associations between models in ActiveRecord in this Rails Guide.
Here is an example of how you could write this in an interview:
class Cart < ApplicationRecord
has_many :items
end
class Item < ApplicationRecord
belongs_to :cart
end
The idea is to test whether a candidate knows the basics of defining database models within Ruby on Rails and if they have some skill in architecture. If you are interviewing for a mid-level role, you may be asked to implement or design a migration that will store particular data types within the cart or items. It's possible for an interviewer to dive deeper into this question by adding the concepts of billing, shipping, or tax information. This will be the case if you are interviewing at an ecommerce, payments, or fintech company.
For example, with more details provided by the interviewer, your model for the Cart could end up looking like this:
class Cart < ApplicationRecord
has_many :items
has_one :shipping_address
def sales_tax
if shipping_address.country == 'US'
Taxes.calculate_for_united_states(shipping_address.state)
elsif shipping_address.country == 'CA'
Taxes.calculate_for_canada(shipping_address.state)
end
end
def taxed_items
items.reject(&:tax_free?)
end
def total
subtotal = items.map { |item| item.quantity * item.price }]
taxes = sales_tax * taxed_items.map { |item| item.quantity * item.price }
subtotal + taxes
end
end
#7 If a controller action is being used heavily, how would you improve its performance?
For this question, the interviewer will want to know that you understand the basics of performance optimization in Rails.
One way to improve performance is by adding caching using Rails's built-in cache store methods. The company you are interviewing at may be using Memcached or Redis (or both!) to store the caching data. You can ask them about this to indicate more knowledge on the subject of caching and performance optimization.
Here is the Rails Guide to caching.
The interviewer may ask you how you would improve the performance of this controller action, which displays a list of airfare prices for different airlines retrieved from a 3rd party API:
class AirfareController < ApplicationController
def index
@airfares = TravelPriceAPI.retrieve_prices_for(params[:city_from], params[:city_to])
end
end
If there were 100 users hitting that controller action to see the prices for popular destinations, it would result in 100 calls to the 3rd party travel price API.
To relieve the pressure on the 3rd party API, you can introduce caching:
class AirfareController < ApplicationController
def index
cache_key = "airfare/#{params[:city_from]}/params[:city_to]"
@airfares = Rails.cache.fetch(cache_key, expires_in: 10.minutes) do
TravelPriceAPI.retrieve_prices_for(params[:city_from], params[:city_to])
end
end
end
The effect of this is that the airfare prices will be cached based on the city that the user is flying from and the city they are flying to. The cache expiration time, also known as a TTL (Time To Live), is set to 10 minutes to ensure users see relatively fresh prices without overloading the 3rd party API.
In an ideal situation, 100 users accessing this controller action, all from the same city and flying to the same destination and within the 10 minute time span, would only result in one API request. This is a huge improvement over the 100 API requests we would have made.
More realistically, we'll have users from different cities, creating additional API requests. However, we would still get a performance improvement if a user hits the refresh button a few times on the page.
Another way of improving performance is simply to add more hardware: either by scaling up the servers being used through additional memory or CPUs or by scaling out and adding more servers. For instance, you can ask the interviewer what sort of AWS (Amazon Web Services), Google Cloud Platform, or Microsoft Azure instance types they are using. Or if they have auto-scaling groups setup. This will not always work, for instancem with our example above, where we were relying on a 3rd party API for airfare prices. Scaling up without caching would increase the load on the 3rd party API and offer no relief for our own Rails servers.
Here are links to some autoscaling guides:
- Amazon Web Services EC2 Auto Scaling Groups
- Best Practices for Auto Scaling for Microsoft Azure
- Google Cloud Platform Auto Scaling
#8 Given these models, how would you put them into a single database table? And what are the advantages of this?
If the company you interview at is working on a complex Rails app, the chances are good that they use sub-classed ActiveRecord models. These are models that use STI (Single Table Inheritance) to store models in a single database table. With single table inheritance, we will have one database table with an additional column created that stores the type of subclass.
For example, we have 4 models: FleetVehicle which is sub-classed as Car, Truck, Scooter. Without single table inheritance we would have three database tables, one for each subclass. However, by using single table inheritance, we will have only one database table which stores the type of each subclass.
Here's how the code looks before using single-table inheritance:
class FleetCar < ApplicationRecord; end
class FleetTruck < ApplicationRecord; end
class FleetScooter < ApplicationRecord; end
That's three separate database tables and any commonality between models would have to be shared using modules and mixins and concerns.
Here's how the models look after applying single-table inheritance:
class FleetVehicle < ActiveRecord::Base; end
class Car < FleetVehicle; end
class Truck < FleetVehicle; end
class Scooter < FleetVehicle; end
This results in just one database table with an additional column to specify the type of object.
The main advantage is that it simplifies queries and reduces the workload on the database. Instead of joining multiple tables to find a particular type of model, you can query one table. This is especially helpful if you are trying to ensure a unique constraint for certain model fields. For instance, you might want all products in an ecommerce store to be in a single table so that the product serial numbers are unique, or you'd want all vehicles in your fleet to have a unique id.
In the Rails documentation for ActiveRecord there is another example of how to use Single-Table Inheritance: https://api.rubyonrails.org/v6.0.2.1/classes/ActiveRecord/Inheritance.html
Conclusion
You should be able to answer these questions before going in for an interview. If you weren't able to find an answer, hopefully these questions helped you identify what you need to work on.
Let us know below if you know any other Ruby on Rails interview questions!
Learn Ruby on Rails by building projects on DevProjects