×

ruby · level 3 · unit 7 · lesson 3

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

A runs your code automatically at a set moment.

People type emails with stray spaces and capitals. Rather than tidying them in every place that saves a user, the model declares a callback: code that runs automatically at a set moment. means: right before every save, run this.

Like validates, before_save is a class macro that only stores the block. save runs each stored callback with instance_eval, in the order they were declared, and only then stores the record. Rails also accepts a method name, as in before_save :tidy_email, and calls it with send.

class User < Struct.new(:email, keyword_init: true)
  CALLBACKS = []
  def self.before_save(&callback)
    CALLBACKS << callback
  end
  before_save { self.email = email.strip }
  before_save { self.email = email.downcase }
  def save
    CALLBACKS.each { |callback| instance_eval(&callback) }
    puts "Saved #{email}"
  end
end
User.new(email: "  Ana@Example.COM ").save

Inside a callback, write self.email =, because a bare email = would make a new local variable instead.