Rails 7 has introduced a new setting called
enumerate_columns_in_select_statements for enumerating columns in activerecord
select query statements by which we can avoid common
Rails uses prepared statements for database query efficiency. When prepared statements are being used, the repeated queries will be cached based on the prepared statement query plan at Postgres database level. This cached value will become invalid when the returned results are changed.
Whenever we make any schema changes to database tables while application is
running, the cached select statements with wildcard column definition will raise
PreparedStatementCacheExpired error since the query output has modified.
1=> User.limit(10) 2=> SELECT * FROM users LIMIT 10
If we use the select query with
*, then any change in the database schema for
the particular table (eg: users) will invalidate the prepared statement cache
and result in the
PreparedStatementCacheExpired error. The solution here is to
mention the columns explicitly in the select statement as shown below:
1=> SELECT "first_name,last_name,email ..." FROM users LIMIT 10
Rails 7 onwards
Rails 7 adds a new setting, by which we can ensure all select statements are
generated by enumerating the columns explicitly. Hence any modifications to the
database schema won't result in
PreparedStatementCacheExpired, instead the
prepared statements will be changed and the respective query will be cached
freshly by the Postgres database.
We can either configure the setting for all models or at specific model level.
1# config/application.rb 2module MyApp 3 class Application < Rails::Application 4 config.active_record.enumerate_columns_in_select_statements = true 5 end 6end 7 8# User model specific 9class User < ApplicationRecord 10 self.enumerate_columns_in_select_statements = true 11end
When the setting value is set to
true the select statement will always
contains columns explicitly.
1=> User.limit(10) 2=> SELECT "first_name,last_name,email ..." FROM users LIMIT 10
Check out this pull request for more details.