📖 Scenario: You are building a simple blog application where each Post can have many Comments. You want to automatically update a comments_count attribute on the Post model whenever a comment is created or destroyed.
🎯 Goal: Build a Rails model setup that uses association callbacks to update the comments_count on the Post model whenever comments are added or removed.
📋 What You'll Learn
Create a Post model with a comments_count integer attribute initialized to 0
Create a Comment model that belongs to Post
Use after_add and after_remove association callbacks on Post to update comments_count
Ensure the comments_count is incremented when a comment is added and decremented when a comment is removed
💡 Why This Matters
🌍 Real World
Association callbacks are useful in apps where related data needs automatic updates, like counting comments, likes, or tags.
💼 Career
Understanding association callbacks helps you maintain data integrity and write cleaner Rails models, a key skill for Rails developers.
Progress0 / 4 steps
1
Create the Post and Comment models with association
Create a Post model with a comments_count attribute set to 0 and a has_many :comments association. Also create a Comment model with a belongs_to :post association.
Ruby on Rails
Hint
Use has_many :comments in Post and belongs_to :post in Comment. Use attribute :comments_count, :integer, default: 0 to set default.
2
Add association callback configuration on Post
In the Post model, add after_add and after_remove callbacks on the comments association. Use method names increment_comments_count and decrement_comments_count respectively.
Ruby on Rails
Hint
Add after_add: :increment_comments_count and after_remove: :decrement_comments_count to has_many :comments. Define empty methods increment_comments_count and decrement_comments_count.
3
Implement the increment and decrement methods
In the Post model, implement the increment_comments_count(comment) method to increase comments_count by 1 and save the record. Implement decrement_comments_count(comment) to decrease comments_count by 1 and save the record.
Ruby on Rails
Hint
Use self.comments_count += 1 and save inside increment_comments_count. Use self.comments_count -= 1 and save inside decrement_comments_count.
4
Complete the Post model with association callbacks
Ensure the Post model has the full association with after_add: :increment_comments_count and after_remove: :decrement_comments_count callbacks, and the methods increment_comments_count and decrement_comments_count correctly update and save comments_count.
Ruby on Rails
Hint
Review the Post model to confirm the association callbacks and methods are correctly implemented.
Practice
(1/5)
1. What is the purpose of after_add and after_remove callbacks in Rails associations?
easy
A. To define database indexes on associations
B. To validate the presence of associated records
C. To preload associated records for performance
D. To run code automatically when related records are added or removed
Solution
Step 1: Understand association callbacks
Rails provides after_add and after_remove callbacks to trigger code when associated records change.
Step 2: Identify their purpose
These callbacks run automatically when you add or remove related records, helping keep data in sync.
Final Answer:
To run code automatically when related records are added or removed -> Option D
Quick Check:
Association callbacks = automatic code on add/remove [OK]
Hint: Callbacks run code on add/remove related records [OK]
Common Mistakes:
Confusing callbacks with validations
Thinking callbacks preload data
Assuming callbacks define indexes
2. Which is the correct syntax to add an after_add callback to a has_many association named comments in a Rails model?
easy
A. has_many :comments, after_add: :notify_comment_added
B. has_many :comments, after_add => :notify_comment_added
C. has_many :comments do after_add :notify_comment_added end
D. has_many :comments, callback_after_add: :notify_comment_added
Solution
Step 1: Recall correct hash syntax for options
Rails uses symbol keys with colon and value pairs like after_add: :method_name.
Step 2: Match syntax to association
The correct syntax is has_many :comments, after_add: :notify_comment_added.
Final Answer:
has_many :comments, after_add: :notify_comment_added -> Option A
Quick Check:
Use colon syntax for options in associations [OK]
Hint: Use colon syntax for options in associations [OK]
Common Mistakes:
Using hash rocket => instead of colon :
Trying to define callback inside block
Using wrong option name like callback_after_add
3. Given the following code, what will be printed when a new comment is added to a Post?
class Post < ApplicationRecord
has_many :comments, after_add: :log_comment_added
def log_comment_added(comment)
puts "Comment added: #{comment.body}"
end
end
post = Post.new
post.comments << Comment.new(body: 'Nice post!')
medium
A. No output
B. Comment added: Nice post!
C. Error: undefined method log_comment_added
D. Comment added:
Solution
Step 1: Understand after_add callback behavior
The after_add callback calls log_comment_added with the new comment when added.
Step 2: Check the method output
The method prints "Comment added: " plus the comment's body, which is "Nice post!".
Final Answer:
Comment added: Nice post! -> Option B
Quick Check:
after_add calls method with new record [OK]
Hint: after_add calls method with added record [OK]
Common Mistakes:
Expecting no output
Thinking callback is not triggered on << operator
Assuming method is missing error
4. Identify the error in this Rails model code using after_remove callback:
class User < ApplicationRecord
has_many :posts, after_remove: :notify_post_removed
def notify_post_removed
puts 'Post removed'
end
end
medium
A. The callback method must accept the removed record as an argument
B. The callback name should be after_remove_post
C. The after_remove option is not valid for has_many
D. The method should be private
Solution
Step 1: Check callback method signature
Callbacks like after_remove receive the removed record as an argument.
Step 2: Compare method definition
The method notify_post_removed has no parameters, so it will cause an error.
Final Answer:
The callback method must accept the removed record as an argument -> Option A
Quick Check:
Callback methods need removed record argument [OK]
Hint: Callback methods must accept the changed record argument [OK]
Common Mistakes:
Defining callback method without parameters
Using invalid callback option name
Thinking method visibility causes error
5. You want to track when tags are added or removed from an Article model using has_many :tags. You want to update a counter on Article each time tags change. Which is the best way to implement this using association callbacks?
hard
A. Use before_save callback on Article to count tags
B. Override the tags= setter method to update the counter
C. Use after_add and after_remove callbacks on has_many :tags to update the counter method
D. Manually call a method to update the counter after changing tags
Solution
Step 1: Understand the goal
You want to update a counter automatically when tags are added or removed.
Step 2: Choose appropriate callback
after_add and after_remove on has_many :tags run code exactly when tags change.
Step 3: Compare other options
Overriding setter or using before_save is less direct and can miss changes; manual calls are error-prone.
Final Answer:
Use after_add and after_remove callbacks on has_many :tags to update the counter method -> Option C
Quick Check:
Use association callbacks for automatic related record updates [OK]
Hint: Use after_add and after_remove for automatic updates [OK]
Common Mistakes:
Overriding setter unnecessarily
Using before_save which may miss association changes
Forgetting to automate updates
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.