Rails 7 adds the partial_inserts
config to config.active_record
that is used to control partial writes when creating a new record.
config.active_record.partial_inserts
is a boolean value and controls whether or not partial writes are used when creating new records (i.e. whether inserts only set attributes that are different from the default).
Configuring config.active_record.partial_inserts
In a newly created Rails 7.0 application, config.load_defaults 7.0
is set by default in application.rb
. The default value of partial_inserts
for config.load_defaults 7.0
is false and for config.load_defaults < 7.0
it is true. To opt-in:
# config/environments/development.rb
config.active_record.partial_inserts = true
Also, partial_writes
is deprecated in favor of partial_inserts
and partial_updates
. We will discuss partial_inserts
in this blog.
2.7.0 :001 > ActiveRecord::Base.partial_writes
# DEPRECATION WARNING: ActiveRecord::Base.partial_writes is deprecated and will be removed in Rails 7.1. Use `partial_updates` and `partial_inserts` instead. (called from irb_binding at (irb):3)
# => false
2.7.0 :002 > ActiveRecord::Base.partial_writes = false
# DEPRECATION WARNING: `ActiveRecord::Base.partial_writes=` is deprecated and will be removed in Rails 7.1. Use `partial_updates=` and `partial_inserts=` instead. (called from irb_binding at (irb):4)
Let's take an example of the following Article
model structure:
# == Schema Information
#
# Table name: articles
#
# id :integer(4)
# title :string
# body :text default('New Article')
# created_at :datetime
# updated_at :datetime
class Article < ApplicationRecord
end
-
When
config.active_record.partial_inserts = true
-
When inserting new records, only the fields that have been changed from the defaults will be included in the
INSERT
statement. -
In the below example, the unchanged field
body
is not included in theINSERT
query.
Loading development environment (Rails 7.0.0.alpha)
2.7.0 :001 > Rails.configuration.active_record.partial_inserts => true 2.7.0 :002 > Article.new(title: 'Rails 7').save
(1.1ms) SELECT sqlite_version(*) TRANSACTION (0.1ms) begin transaction Article Create (1.7ms) INSERT INTO "articles" ("title", "created_at", "updated_at") VALUES (?, ?, ?) [["title", "Rails 7"], ["created_at", "2021-09-06 04:13:01.580819"], ["updated_at", "2021-09-06 04:13:01.580819"]] TRANSACTION (1.9ms) commit transaction => true
-
-
When
config.active_record.partial_inserts = false
-
This default means that all columns will be referenced in
INSERT
queries regardless of whether they have a default or not. The other fields will be populated by the database. -
In the below example, the unchanged field
body
is included in theINSERT
query.
Loading development environment (Rails 7.0.0.alpha)
2.7.0 :001 > Rails.configuration.active_record.partial_inserts => false 2.7.0 :002 > Article.new(title: 'Rails 7').save
TRANSACTION (0.1ms) begin transaction Article Create (0.6ms) INSERT INTO "articles" ("title", "body", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["title", "Rails 7"], ["body", "New Article"], ["created_at", "2021-09-29 07:46:46.236842"], ["updated_at", "2021-09-29 07:46:46.236842"]] TRANSACTION (5.6ms) commit transaction => true
-
Note:
- Additionally,
partial_inserts
prevents removing the default value of a column safely. If a migration removes the default value of a column, this option would cause old processes to no longer to be able to create new records. - If you need to remove a column, you should first use
ignored_columns
to stop using it.ActiveRecord::Base.ignored_columns
is introduced in Rails 5 to make some columns invisible from ActiveRecord. Ignored columns won’t have attribute accessors defined, and won’t be referenced inSQL
queries.
In your rails application, based on your requirements you can set the partial_inserts
config value. Hope this article has helped you to understand the use of partial_inserts
config of active-record.
Thank you for reading. ❤️