Today I am working on some basic db calls to tough on some of those simple concepts that feels like I learned ages ago. Here is the quiz and my answers below:
ActiveRecord Lookups Quiz
Without looking for help online write the following queries:
1. Find an author with an id
of 9
.
Answer: Author.find(9)
Why: Using the Find
method only takes id
numbers as inputs and returns a single value based on that input.
2. Find all authors with a last_name
of Brown
.
Answer: Author.find_by(last_name: 'Brown')
Why: find_by
searches by attributes of the model that it is called on and returns the first instances where the condition is met.
3. Find the first author with a last_name
of Brown
.
Answer: Author.find_by(last_name: 'Brown)
Why: refer back to question 2
4. Find all articles created in the last 5 days.
Answer: Article.where("created_at >= ?", 5.days.ago)
Why: Here I decided to use sql paired with AR (ActiveRecord) to simplify my code. Using .where
was the best choice in my opinion because I am searching the whole database to see is my condition (article being created in the last 5 days) has been met. If there haven't been any articles created then this method should return an empty array.
Using only one call to the database:
5. Find all users with a last_name
of 'Brown' and return the first user with a first_name
of 'Nancy'.
Answer: User.where(last_name: 'Brown').find_by(first_name: 'Nancy')
Why: .where
searches the db for users where the last_name
== 'Brown'. This returns an array, on that array I then am using find_by to find the first instance where the first_name is 'Nancy'.
6. Find all articles created in the last 5 days. Display the article title and author's last_name for each article.
- Article.where(created_at: 5.days.ago..Time.now) .includes(:author) .select("title, users.last_name as author_last_name") .map { |article| [article.title, article.author_last_name] }
Bonus Round
7. What's the danger of using update_attribute
vs update_attributes
?
Answer and Why: 'update_attribute' changes a singular attribute WITHOUT checking against validations and callbacks. While 'update_attributes' changes multiple the attributes and checks the validations and callbacks. So the danger would be that using update_attribute' you may accidentally save an attribute that is an invalid value.
8. Imagine we are creating and loading users based on data received from an external service (attributes
in this example).
Refactor the method below to use .first_or_initialize
and .tap
:
def self.find_or_create_from_external_service(attributes = {})
user = User.find_by_login(attributes[:login])
if user.nil?
user = User.create(login: attributes[:login], email: attributes[:email])
end
user
end
refactor:
def self.find_or_create_from_external_service(attributes = {})
User.where(login: attributes[:login]).first_or_initialize.tap do |user|
user.update(email: attributes[:email]) if user.new_record?
user.save
end
end
Top comments (0)