ActiveRecord
module in Rails is one of the core components which have contributed to the success and popularity of the framework. A few months back we published a quiz, testing knowledge of the ActiveRecord
API. In this short post we review average performance against this quiz and identify the question that posed the biggest challenge to our quiz-takers.
Introduction
Our most popular quiz to-date has been that on Rails ActiveRecord
API.
This was a 10-question quiz, allowing you to test your knowledge on various aspects of ActiveRecord
, a key building block in the Rails ecosystem.
Collecting the data from all respondants we can reflect on how people fared, and which questions posed the greatest challenge to the collective.
Breakdown by score
At the time of writing the quiz has a total of 1779 attempts registered, with a mean score of 35%. Multiple attempts may have been registered by an individual user, but this is unlikely to impact the conclusions drawn. The graph below shows the distribution of scores:
The mean of 35% was surprisingly low, but you can see from the bar chart that the modal scoring interval was 40-49. The mean is suppressed owing to a skew in the data towards lower scores; this is on account of the higher scoring buckets being relatively sparsely populated. If you achieved a score of over 70%, well done, you are in the 95th percentile. If you achieved a score of over 80% you are in the top 1.5%.
Breakdown by question
We can look at how users performed against the individual questions. The bar chart below summarizes the percentage of correct responses for each question, you can click on the individual bars to see a screenshot of the question in each case.
The Hardest Question
Question 9 turned out the be the question which posed the most problems, with a mere
The domain model is pretty simple; the User
class has_many :posts
, and each Post
has a title
attribute.
The User.joins
pattern is used to filter users by the associated record, but it will not load the associated record. As a result, each time we access an
associated Post
object that will need to be loaded from the database. This is often the cause of the notorious N+1 problem.
The User.preload
pattern will load both the User
models and the associated Post
models into memory. However it achieves this
using two separate queries: one query to load the User
records and a separate query to load all Post
records associated with these users.
As a result of this two-stage loading, you are not able to filter by attributes of associated records when using preload
.
The User.eager_load
pattern will load both the User
records and the associated Post
records using a single
LEFT OUTER JOIN
query. So this is a correct answer.
The User.includes
pattern does the same as User.preload
, but will also allow you to filter your queries by values in the associated table.
If you do apply a filter to the associated table by applying a where
clause, then the includes
method will load both the
User
and Post
records in a single LEFT OUTER JOIN
query. So this is also a correct answer.
Summary
We have presented a short analysis of the results registered against our recently published Rails ActiveRecord API Quiz.
The most challenging question probed our understanding of the difference between preload
, eager_load
, joins
and includes
for loading associated records in Rails.
If you have any thoughts or feedback, or ideas for future quizzes, please share using the comments section below. Thanks!
References
- The original quiz on Rails ActiveRecord API
- Concise BigBinary blog post discussing the differeces between preload, eager-load, join and includes
Comments
There are no existing comments
Got your own view or feedback? Share it with us below …