Rails 7 allows setting timestamps on insert_all/upsert_all record creation
source link: https://blog.saeloun.com/2022/01/18/rails-7-updates-timestamp-for-insert-and-upsert-all-queries
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Rails 7 allows setting timestamps on insert_all/upsert_all record creation
Jan 18, 2022 , by Swaathi Kakarla
1 minute read
ActiveRecord is one of the most useful utilities in the Rails toolkit. It allows us to perform complex database queries while abstracting the adapter, essentially making a database “pluggable”.
However,
some edge cases stand out like a sore thumb.
One such query is the ability to set values to the standard Rails
timestamps which are available across models.
Namely,
created_at
,
created_on
,
updated_at
,
updated_on
.
In a typical model insertion, one does not need to actively set values for the timestamps. They are set by the underlying framework at the time of insertion.
> Book.create(title: "Ruby on Rails Tutorial: Learn Web Development with Rails")
> Book.last.created_at
=> Tue, 18 Jan 2022
Before
One would expect consistent action across similar queries. Let’s have a look at mass insertion queries.
> Book.insert_all[
{title: "Ruby on Rails Tutorial: Learn Web Development with Rails"},
{title: "Service-Oriented Design with Ruby and Rails"}
]
=> Traceback (most recent call last):
1: from (irb):1
ActiveRecord::NotNullViolation (SQLite3::ConstraintException: NOT NULL constraint failed: books.created_at)
It raises an unexpected exception ActiveRecord::NotNullViolation
,
since a database constraint is present on the created_at
column.
This leaves us with only one option — manually providing values for all timestamp columns.
The only way to make this work is,
> Book.insert_all[
{title: "Ruby on Rails Tutorial: Learn Web Development with Rails", created_at: Time.now, updated_at: Time.now},
{title: "Service-Oriented Design with Ruby and Rails", created_at: Time.now, updated_at: Time.now}
]
=> #<ActiveRecord::Result:0x00007f9ffcdfb620 @columns=[], @rows=[], @hash_rows=nil, @column_types={}>
After
Fortunately, Rails 7 allow setting timestamps on insert_all / upsert_all record queries.
> Book.insert_all[
{title: "Ruby on Rails Tutorial: Learn Web Development with Rails"},
{title: "Service-Oriented Design with Ruby and Rails"}
]
=> #<ActiveRecord::Result:0x00007f9ffcdfb620 @columns=[], @rows=[], @hash_rows=nil, @column_types={}>
We have the option to override this configuration using,
> Book.insert_all[
{title: "Ruby on Rails Tutorial: Learn Web Development with Rails"},
{title: "Service-Oriented Design with Ruby and Rails"}
], record_timestamps: false
=> Traceback (most recent call last):
1: from (irb):1
ActiveRecord::NotNullViolation (SQLite3::ConstraintException: NOT NULL constraint failed: books.created_at)
Which, as expected, will result in the previous error.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK