ruby · level 3 · unit 7 · lesson 3
- meet it
- guess first
- your turn
- fix it
- 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.
guess first
The slug is made before the title is tidied. What will this show?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
class Post < Struct.new(:title, :slug, keyword_init: true)
CALLBACKS = []
def self.before_save(&callback)
CALLBACKS << callback
end
before_save { self.slug = title.downcase.gsub(" ", "-") }
before_save { self.title = title.strip }
def save
CALLBACKS.each { |callback| instance_eval(&callback) }
p [title, slug]
end
end
Post.new(title: " Hello World ").save
your turn
Your turn. Tidy a pet before it is saved.
In the first blank, use the macro that stores a callback. In the second, choose the text method that turns DOG into dog.
fix it
The tidy-up callback crashes. Fix it.
- The error says
stripwas called onnil. Whichemailis on the right of the=? email = ...makes a new local variable, which starts asnil. To call the setter, Ruby needsself..- Write
self.email = email.strip.downcaseinside the block on line 6, then press run.
nailed it
your model tidies itself before saving. :D
- A callback runs your code at a set moment.
before_savestores callbacks, andsaveruns them in order.- Inside a callback, set fields with
self..
new words in your collection
- callback
- before_save
This lesson isn’t saved. A free account remembers every lesson you finish.