Bird
Raised Fist0
Ruby on Railsframework~10 mins

Association callbacks in Ruby on Rails - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Association callbacks
Trigger action on parent model
↓
Check association callback type
↓
before_add
↓
Run callback method if defined
↓
Modify associated objects or state
↓
Continue action
When you add or remove associated objects in Rails, specific callbacks run before or after the change to let you customize behavior.
Execution Sample
Ruby on Rails
class Cart < ApplicationRecord
  has_many :items, before_add: :check_stock

  def check_stock(item)
    raise 'Out of stock' if item.stock <= 0
  end
end
This code runs a method before adding an item to a cart to check if the item is in stock.
Execution Table
StepActionCallback TriggeredCallback Method CalledEffectResult
1Add item with stock=5 to cart.itemsbefore_addcheck_stock(item)Checks item stockPasses, item added
2Add item with stock=0 to cart.itemsbefore_addcheck_stock(item)Checks item stockRaises 'Out of stock' error, item not added
3Remove item from cart.itemsbefore_removenone (not defined)No callbackItem removed normally
4Add item to cart.itemsafter_addnone (not defined)No callbackItem added normally
5Remove item from cart.itemsafter_removenone (not defined)No callbackItem removed normally
💡 Execution stops after each add/remove action completes or raises error.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3After Step 4After Step 5
cart.items.count010010
item.stockvaries50555
Key Moments - 2 Insights
Why does adding an item with zero stock raise an error?
Because the before_add callback runs check_stock, which raises an error if stock is 0, stopping the add (see execution_table step 2).
What happens if no callback method is defined for after_add or before_remove?
No callback runs, so the add or remove proceeds normally without extra checks (see execution_table steps 3,4,5).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the cart.items.count after step 1?
A1
B0
C2
DUndefined
💡 Hint
Check the variable_tracker row for cart.items.count after Step 1.
At which step does the before_add callback prevent adding an item?
AStep 1
BStep 3
CStep 2
DStep 4
💡 Hint
Look at execution_table where an error is raised during before_add.
If we define an after_remove callback, what would happen at step 5?
ACallback method runs before item removal
BCallback method runs after item removal
CNo callback runs
DItem removal is blocked
💡 Hint
After_remove callbacks run after removal actions, see concept_flow.
Concept Snapshot
Association callbacks in Rails run methods before or after adding/removing associated objects.
Use options like before_add, after_add, before_remove, after_remove in associations.
Callbacks let you check or modify objects during association changes.
If a before_* callback raises an error, the change is stopped.
Define callback methods in the model to customize behavior.
Full Transcript
In Rails, association callbacks let you run code when you add or remove objects from associations like has_many. For example, before_add runs before adding an object, and after_remove runs after removing one. You define methods in your model and link them with options like before_add: :method_name. When you add an item to a cart, the before_add callback can check if the item is in stock and stop the add if not. The execution table shows adding an item with stock 5 passes, but with stock 0 raises an error. Removing items without callbacks just works normally. This helps keep your data consistent and lets you run custom logic during association changes.

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

  1. Step 1: Understand association callbacks

    Rails provides after_add and after_remove callbacks to trigger code when associated records change.
  2. Step 2: Identify their purpose

    These callbacks run automatically when you add or remove related records, helping keep data in sync.
  3. Final Answer:

    To run code automatically when related records are added or removed -> Option D
  4. 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

  1. Step 1: Recall correct hash syntax for options

    Rails uses symbol keys with colon and value pairs like after_add: :method_name.
  2. Step 2: Match syntax to association

    The correct syntax is has_many :comments, after_add: :notify_comment_added.
  3. Final Answer:

    has_many :comments, after_add: :notify_comment_added -> Option A
  4. 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

  1. Step 1: Understand after_add callback behavior

    The after_add callback calls log_comment_added with the new comment when added.
  2. Step 2: Check the method output

    The method prints "Comment added: " plus the comment's body, which is "Nice post!".
  3. Final Answer:

    Comment added: Nice post! -> Option B
  4. 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

  1. Step 1: Check callback method signature

    Callbacks like after_remove receive the removed record as an argument.
  2. Step 2: Compare method definition

    The method notify_post_removed has no parameters, so it will cause an error.
  3. Final Answer:

    The callback method must accept the removed record as an argument -> Option A
  4. 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

  1. Step 1: Understand the goal

    You want to update a counter automatically when tags are added or removed.
  2. Step 2: Choose appropriate callback

    after_add and after_remove on has_many :tags run code exactly when tags change.
  3. Step 3: Compare other options

    Overriding setter or using before_save is less direct and can miss changes; manual calls are error-prone.
  4. Final Answer:

    Use after_add and after_remove callbacks on has_many :tags to update the counter method -> Option C
  5. 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 unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard