Use a bang (!
).
On a model that requires many things (including a title), create
fails and triggers your rollback:
> Post.create(title: nil)
(0.1ms) BEGIN
Post Exists (0.2ms) SELECT 1 AS one FROM "posts" WHERE "posts"."slug" IS NULL LIMIT $1 [["LIMIT", 1]]
(0.1ms) ROLLBACK
=> #<Post:0x007fa44c934fc0
id: nil,
developer_id: nil,
body: nil,
created_at: nil,
updated_at: nil,
channel_id: nil,
title: nil,
slug: nil,
likes: 1,
tweeted: false,
published_at: nil,
max_likes: 1>
With the bang, the creation fails fast and an RecordInvalid
error is raised:
> Post.create!(title: nil)
(0.1ms) BEGIN
Post Exists (0.2ms) SELECT 1 AS one FROM "posts" WHERE "posts"."slug" IS NULL LIMIT $1 [["LIMIT", 1]]
(0.1ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Body can't be blank, Channel can't be blank, Developer can't be blank, Title can't be blank
from /Users/dev/.asdf/installs/ruby/2.3.3/lib/ruby/gems/2.3.0/gems/activerecord-5.0.1/lib/active_record/validations.rb:78:in `raise_validation_error'
To build on the OP, one could use update_attributes
and update_attributes!
to produce the two behaviors:
> Post.first.update_attributes(title: nil)
Post Load (0.2ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1 [["LIMIT", 1]]
(0.1ms) BEGIN
Developer Load (0.2ms) SELECT "developers".* FROM "developers" WHERE "developers"."id" = $1 LIMIT $2 [["id", 4], ["LIMIT", 1]]
Post Exists (0.2ms) SELECT 1 AS one FROM "posts" WHERE "posts"."slug" = $1 AND ("posts"."id" != $2) LIMIT $3 [["slug", "81e668bc4e"], ["id", 1], ["LIMIT", 1]]
(0.1ms) ROLLBACK
=> false
> Post.first.update_attributes!(title: nil)
Post Load (0.2ms) SELECT "posts".* FROM "posts" ORDER BY "posts"."id" ASC LIMIT $1 [["LIMIT", 1]]
(0.1ms) BEGIN
Developer Load (0.2ms) SELECT "developers".* FROM "developers" WHERE "developers"."id" = $1 LIMIT $2 [["id", 4], ["LIMIT", 1]]
Post Exists (0.2ms) SELECT 1 AS one FROM "posts" WHERE "posts"."slug" = $1 AND ("posts"."id" != $2) LIMIT $3 [["slug", "81e668bc4e"], ["id", 1], ["LIMIT", 1]]
(0.1ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Title can't be blank
from /Users/dev/.asdf/installs/ruby/2.3.3/lib/ruby/gems/2.3.0/gems/activerecord-5.0.1/lib/active_record/validations.rb:78:in `raise_validation_error'
What is !
?
!
in Ruby often means the method will modify the object it is called on. However, ActiveRecord has a different convention; !
methods "are stricter in that they raise the exception."
create docs
validation docs