DEV Community

Germán Alberto Gimenez Silva
Germán Alberto Gimenez Silva

Posted on • Originally published at rubystacknews.com on

Mastering Callbacks in Ruby and Ruby on Rails

February 18, 2025

Callbacks are a powerful tool in Ruby and Ruby on Rails, allowing developers to hook into an object’s lifecycle and execute custom logic at specific points. While they provide a convenient way to automate processes, improper use can lead to hidden complexities and maintainability issues. Let’s dive deep into what callbacks are, how they work, and best practices for using them effectively.


Need Expert Ruby on Rails Developers to Elevate Your Project?

Fill out our form! >>


Need Expert Ruby on Rails Developers to Elevate Your Project?


What Are Callbacks?

In the simplest terms, callbacks are methods that get executed at predefined points in an object’s lifecycle. In Ruby, callbacks can be implemented using blocks, Procs, or custom methods. However, Rails takes this concept further by integrating callbacks deeply into Active Record models.

Callbacks in Ruby

While Ruby doesn’t have built-in lifecycle callbacks like Rails, you can implement them using define_method, Procs, or event-driven programming.

Example of a simple callback system in Ruby:

class Task
  def initialize
    @before_save_callbacks = []
  end

  def before_save(&block)
    @before_save_callbacks << block
  end

  def save
    @before_save_callbacks.each(&:call)
    puts "Saving task..."
  end
end

# Usage
my_task = Task.new
my_task.before_save { puts "Preparing to save..." }
my_task.save 
Enter fullscreen mode Exit fullscreen mode

Active Record Callbacks in Rails

Active Record models in Rails provide several built-in callbacks that allow developers to execute code before or after database operations. These are useful for enforcing business logic, cleaning up data, or sending notifications.

Common Active Record Callbacks

Before Callbacks (Executed before an action)

  • before_validation – Runs before validations are performed.
  • before_save – Runs before saving (on both create and update actions).
  • before_create – Runs only before creating a new record.
  • before_update – Runs before updating an existing record.

Around Callbacks (Wraps the action)

  • around_save – Runs before and after saving a record, useful for transactions.

After Callbacks (Executed after an action)

  • after_save – Runs after saving (both create and update actions).
  • after_create – Runs only after a record is created.
  • after_update – Runs only after an update operation.
  • after_commit – Runs after a transaction is committed.

Example Usage in Rails

class User < ApplicationRecord
  before_save :normalize_name
  after_create :send_welcome_email

  private

  def normalize_name
    self.name = name.capitalize
  end

  def send_welcome_email
    UserMailer.welcome_email(self).deliver_later
  end
end 
Enter fullscreen mode Exit fullscreen mode

Best Practices for Using Callbacks

✅ Use Callbacks for Database-Specific Logic

Callbacks work best when they handle tasks directly related to the database operation, such as formatting data before saving.

❌ Avoid Business Logic in Callbacks

Keeping business logic inside callbacks can make your models harder to test and debug. Instead, use service objects.

✅ Use after_commit for External Calls

If you need to trigger an email or API request, use after_commit to ensure the database transaction completes successfully.

❌ Don’t Overuse Callbacks

Excessive callbacks can lead to unexpected side effects and tightly coupled code. If you find yourself adding multiple callbacks, consider extracting logic into a separate class.

Alternatives to Callbacks

If callbacks become overwhelming, consider using:

  • Service Objects : Encapsulate business logic into separate classes.
  • Observers : Listen for model changes without modifying the model.
  • Event-Driven Systems : Use tools like Sidekiq or Active Job for background tasks.

Final Thoughts

Callbacks are a great tool when used wisely. They provide a powerful way to automate model behavior in Rails, but they should be used carefully to avoid hidden complexity. When working with callbacks, always ask yourself: “Should this logic be inside the model, or does it belong elsewhere?”

How do you use callbacks in your projects? Have you ever faced issues with them? Let’s discuss in the comments!

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed: Zero in on just the tests that failed in your previous run
  • 2:34 --only-changed: Test only the spec files you've modified in git
  • 4:27 --repeat-each: Run tests multiple times to catch flaky behavior before it reaches production
  • 5:15 --forbid-only: Prevent accidental test.only commits from breaking your CI pipeline
  • 5:51 --ui --headed --workers 1: Debug visually with browser windows and sequential test execution

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Watch Full Video 📹️

Top comments (0)

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay