mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
dcc2530af7
`cattr_accessor` rely on class variables which has terrible performance on long ancestor chains. See https://bugs.ruby-lang.org/issues/17763 for a detailed description of the problem. In comparison `class_attribute` on `ActiveRecord::Base` is almost 7x faster: ``` Calculating ------------------------------------- logger 1.700M (± 0.9%) i/s - 8.667M in 5.097595s clogger 11.556M (± 0.9%) i/s - 58.806M in 5.089282s Comparison: clogger: 11555754.2 i/s logger: 1700280.4 i/s - 6.80x (± 0.00) slower ``` This is because `ActiveRecord::Base.ancestors.size == 62`.
703 lines
23 KiB
Markdown
703 lines
23 KiB
Markdown
* `ActiveRecord::Base.logger` is now a `class_attribute`.
|
|
|
|
This means it can no longer be accessed directly through `@@logger`, and that setting `logger =`
|
|
on a subclass won't change the parent's logger.
|
|
|
|
*Jean Boussier*
|
|
|
|
* Add `.asc.nulls_first` for all databases. Unfortunately MySQL still doesn't like `nulls_last`.
|
|
|
|
*Keenan Brock*
|
|
|
|
* Improve performance of `one?` and `many?` by limiting the generated count query to 2 results.
|
|
|
|
*Gonzalo Riestra*
|
|
|
|
* Don't check type when using `if_not_exists` on `add_column`.
|
|
|
|
Previously, if a migration called `add_column` with the `if_not_exists` option set to true
|
|
the `column_exists?` check would look for a column with the same name and type as the migration.
|
|
|
|
Recently it was discovered that the type passed to the migration is not always the same type
|
|
as the column after migration. For example a column set to `:mediumblob` in the migration will
|
|
be casted to `binary` when calling `column.type`. Since there is no straightforward way to cast
|
|
the type to the database type without running the migration, we opted to drop the type check from
|
|
`add_column`. This means that migrations adding a duplicate column with a different type will no
|
|
longer raise an error.
|
|
|
|
*Eileen M. Uchitelle*
|
|
|
|
* Log a warning message when running SQLite in production
|
|
|
|
Using SQLite in production ENV is generally discouraged. SQLite is also the default adapter
|
|
in a new Rails application.
|
|
For the above reasons log a warning message when running SQLite in production.
|
|
|
|
The warning can be disabled by setting `config.active_record.sqlite3_production_warning=false`.
|
|
|
|
*Jacopo Beschi*
|
|
|
|
* Add option to disable joins for `has_one` associations.
|
|
|
|
In a multiple database application, associations can't join across
|
|
databases. When set, this option instructs Rails to generate 2 or
|
|
more queries rather than generating joins for `has_one` associations.
|
|
|
|
Set the option on a has one through association:
|
|
|
|
```ruby
|
|
class Person
|
|
belongs_to :dog
|
|
has_one :veterinarian, through: :dog, disable_joins: true
|
|
end
|
|
```
|
|
|
|
Then instead of generating join SQL, two queries are used for `@person.veterinarian`:
|
|
|
|
```
|
|
SELECT "dogs"."id" FROM "dogs" WHERE "dogs"."person_id" = ? [["person_id", 1]]
|
|
SELECT "veterinarians".* FROM "veterinarians" WHERE "veterinarians"."dog_id" = ? [["dog_id", 1]]
|
|
```
|
|
|
|
*Sarah Vessels*, *Eileen M. Uchitelle*
|
|
|
|
* `Arel::Visitors::Dot` now renders a complete set of properties when visiting
|
|
`Arel::Nodes::SelectCore`, `SelectStatement`, `InsertStatement`, `UpdateStatement`, and
|
|
`DeleteStatement`, which fixes #42026. Previously, some properties were omitted.
|
|
|
|
*Mike Dalessio*
|
|
|
|
* `Arel::Visitors::Dot` now supports `Arel::Nodes::Bin`, `Case`, `CurrentRow`, `Distinct`,
|
|
`DistinctOn`, `Else`, `Except`, `InfixOperation`, `Intersect`, `Lock`, `NotRegexp`, `Quoted`,
|
|
`Regexp`, `UnaryOperation`, `Union`, `UnionAll`, `When`, and `With`. Previously, these node
|
|
types caused an exception to be raised by `Arel::Visitors::Dot#accept`.
|
|
|
|
*Mike Dalessio*
|
|
|
|
* Optimize `remove_columns` to use a single SQL statement.
|
|
|
|
```ruby
|
|
remove_columns :my_table, :col_one, :col_two
|
|
```
|
|
|
|
Now results in the following SQL:
|
|
|
|
```sql
|
|
ALTER TABLE "my_table" DROP COLUMN "col_one", DROP COLUMN "col_two"
|
|
```
|
|
|
|
*Jon Dufresne*
|
|
|
|
* Ensure `has_one` autosave association callbacks get called once.
|
|
|
|
Change the `has_one` autosave callback to be non cyclic as well.
|
|
By doing this the autosave callback are made more consistent for
|
|
all 3 cases: `has_many`, `has_one`, and `belongs_to`.
|
|
|
|
*Petrik de Heus*
|
|
|
|
* Add option to disable joins for associations.
|
|
|
|
In a multiple database application, associations can't join across
|
|
databases. When set, this option instructs Rails to generate 2 or
|
|
more queries rather than generating joins for associations.
|
|
|
|
Set the option on a has many through association:
|
|
|
|
```ruby
|
|
class Dog
|
|
has_many :treats, through: :humans, disable_joins: true
|
|
has_many :humans
|
|
end
|
|
```
|
|
|
|
Then instead of generating join SQL, two queries are used for `@dog.treats`:
|
|
|
|
```
|
|
SELECT "humans"."id" FROM "humans" WHERE "humans"."dog_id" = ? [["dog_id", 1]]
|
|
SELECT "treats".* FROM "treats" WHERE "treats"."human_id" IN (?, ?, ?) [["human_id", 1], ["human_id", 2], ["human_id", 3]]
|
|
```
|
|
|
|
*Eileen M. Uchitelle*, *Aaron Patterson*, *Lee Quarella*
|
|
|
|
* Add setting for enumerating column names in SELECT statements.
|
|
|
|
Adding a column to a PostgreSQL database, for example, while the application is running can
|
|
change the result of wildcard `SELECT *` queries, which invalidates the result
|
|
of cached prepared statements and raises a `PreparedStatementCacheExpired` error.
|
|
|
|
When enabled, Active Record will avoid wildcards and always include column names
|
|
in `SELECT` queries, which will return consistent results and avoid prepared
|
|
statement errors.
|
|
|
|
Before:
|
|
|
|
```ruby
|
|
Book.limit(5)
|
|
# SELECT * FROM books LIMIT 5
|
|
```
|
|
|
|
After:
|
|
|
|
```ruby
|
|
# config/application.rb
|
|
module MyApp
|
|
class Application < Rails::Application
|
|
config.active_record.enumerate_columns_in_select_statements = true
|
|
end
|
|
end
|
|
|
|
# or, configure per-model
|
|
class Book < ApplicationRecord
|
|
self.enumerate_columns_in_select_statements = true
|
|
end
|
|
```
|
|
|
|
```ruby
|
|
Book.limit(5)
|
|
# SELECT id, author_id, name, format, status, language, etc FROM books LIMIT 5
|
|
```
|
|
|
|
*Matt Duszynski*
|
|
|
|
* Allow passing SQL as `on_duplicate` value to `#upsert_all` to make it possible to use raw SQL to update columns on conflict:
|
|
|
|
```ruby
|
|
Book.upsert_all(
|
|
[{ id: 1, status: 1 }, { id: 2, status: 1 }],
|
|
on_duplicate: Arel.sql("status = GREATEST(books.status, EXCLUDED.status)")
|
|
)
|
|
```
|
|
|
|
*Vladimir Dementyev*
|
|
|
|
* Allow passing SQL as `returning` statement to `#upsert_all`:
|
|
|
|
```ruby
|
|
Article.insert_all(
|
|
[
|
|
{ title: "Article 1", slug: "article-1", published: false },
|
|
{ title: "Article 2", slug: "article-2", published: false }
|
|
],
|
|
returning: Arel.sql("id, (xmax = '0') as inserted, name as new_name")
|
|
)
|
|
```
|
|
|
|
*Vladimir Dementyev*
|
|
|
|
* Deprecate `legacy_connection_handling`.
|
|
|
|
*Eileen M. Uchitelle*
|
|
|
|
* Add attribute encryption support.
|
|
|
|
Encrypted attributes are declared at the model level. These
|
|
are regular Active Record attributes backed by a column with
|
|
the same name. The system will transparently encrypt these
|
|
attributes before saving them into the database and will
|
|
decrypt them when retrieving their values.
|
|
|
|
|
|
```ruby
|
|
class Person < ApplicationRecord
|
|
encrypts :name
|
|
encrypts :email_address, deterministic: true
|
|
end
|
|
```
|
|
|
|
You can learn more in the [Active Record Encryption
|
|
guide](https://edgeguides.rubyonrails.org/active_record_encryption.html).
|
|
|
|
*Jorge Manrubia*
|
|
|
|
* Changed Arel predications `contains` and `overlaps` to use
|
|
`quoted_node` so that PostgreSQL arrays are quoted properly.
|
|
|
|
*Bradley Priest*
|
|
|
|
* Add mode argument to record level `strict_loading!`
|
|
|
|
This argument can be used when enabling strict loading for a single record
|
|
to specify that we only want to raise on n plus one queries.
|
|
|
|
```ruby
|
|
developer.strict_loading!(mode: :n_plus_one_only)
|
|
|
|
developer.projects.to_a # Does not raise
|
|
developer.projects.first.client # Raises StrictLoadingViolationError
|
|
```
|
|
|
|
Previously, enabling strict loading would cause any lazily loaded
|
|
association to raise an error. Using `n_plus_one_only` mode allows us to
|
|
lazily load belongs_to, has_many, and other associations that are fetched
|
|
through a single query.
|
|
|
|
*Dinah Shi*
|
|
|
|
* Fix Float::INFINITY assignment to datetime column with postgresql adapter
|
|
|
|
Before:
|
|
|
|
```ruby
|
|
# With this config
|
|
ActiveRecord::Base.time_zone_aware_attributes = true
|
|
|
|
# and the following schema:
|
|
create_table "postgresql_infinities" do |t|
|
|
t.datetime "datetime"
|
|
end
|
|
|
|
# This test fails
|
|
record = PostgresqlInfinity.create!(datetime: Float::INFINITY)
|
|
assert_equal Float::INFINITY, record.datetime # record.datetime gets nil
|
|
```
|
|
|
|
After this commit, `record.datetime` gets `Float::INFINITY` as expected.
|
|
|
|
*Shunichi Ikegami*
|
|
|
|
* Type cast enum values by the original attribute type.
|
|
|
|
The notable thing about this change is that unknown labels will no longer match 0 on MySQL.
|
|
|
|
```ruby
|
|
class Book < ActiveRecord::Base
|
|
enum :status, { proposed: 0, written: 1, published: 2 }
|
|
end
|
|
```
|
|
|
|
Before:
|
|
|
|
```ruby
|
|
# SELECT `books`.* FROM `books` WHERE `books`.`status` = 'prohibited' LIMIT 1
|
|
Book.find_by(status: :prohibited)
|
|
# => #<Book id: 1, status: "proposed", ...> (for mysql2 adapter)
|
|
# => ActiveRecord::StatementInvalid: PG::InvalidTextRepresentation: ERROR: invalid input syntax for type integer: "prohibited" (for postgresql adapter)
|
|
# => nil (for sqlite3 adapter)
|
|
```
|
|
|
|
After:
|
|
|
|
```ruby
|
|
# SELECT `books`.* FROM `books` WHERE `books`.`status` IS NULL LIMIT 1
|
|
Book.find_by(status: :prohibited)
|
|
# => nil (for all adapters)
|
|
```
|
|
|
|
*Ryuta Kamizono*
|
|
|
|
* Fixtures for `has_many :through` associations now load timestamps on join tables
|
|
|
|
Given this fixture:
|
|
|
|
```yml
|
|
### monkeys.yml
|
|
george:
|
|
name: George the Monkey
|
|
fruits: apple
|
|
|
|
### fruits.yml
|
|
apple:
|
|
name: apple
|
|
```
|
|
|
|
If the join table (`fruit_monkeys`) contains `created_at` or `updated_at` columns,
|
|
these will now be populated when loading the fixture. Previously, fixture loading
|
|
would crash if these columns were required, and leave them as null otherwise.
|
|
|
|
*Alex Ghiculescu*
|
|
|
|
* Allow applications to configure the thread pool for async queries
|
|
|
|
Some applications may want one thread pool per database whereas others want to use
|
|
a single global thread pool for all queries. By default, Rails will set `async_query_executor`
|
|
to `nil` which will not initialize any executor. If `load_async` is called and no executor
|
|
has been configured, the query will be executed in the foreground.
|
|
|
|
To create one thread pool for all database connections to use applications can set
|
|
`config.active_record.async_query_executor` to `:global_thread_pool` and optionally define
|
|
`config.active_record.global_executor_concurrency`. This defaults to 4. For applications that want
|
|
to have a thread pool for each database connection, `config.active_record.async_query_executor` can
|
|
be set to `:multi_thread_pool`. The configuration for each thread pool is set in the database
|
|
configuration.
|
|
|
|
*Eileen M. Uchitelle*
|
|
|
|
* Allow new syntax for `enum` to avoid leading `_` from reserved options.
|
|
|
|
Before:
|
|
|
|
```ruby
|
|
class Book < ActiveRecord::Base
|
|
enum status: [ :proposed, :written ], _prefix: true, _scopes: false
|
|
enum cover: [ :hard, :soft ], _suffix: true, _default: :hard
|
|
end
|
|
```
|
|
|
|
After:
|
|
|
|
```ruby
|
|
class Book < ActiveRecord::Base
|
|
enum :status, [ :proposed, :written ], prefix: true, scopes: false
|
|
enum :cover, [ :hard, :soft ], suffix: true, default: :hard
|
|
end
|
|
```
|
|
|
|
*Ryuta Kamizono*
|
|
|
|
* Add `ActiveRecord::Relation#load_async`.
|
|
|
|
This method schedules the query to be performed asynchronously from a thread pool.
|
|
|
|
If the result is accessed before a background thread had the opportunity to perform
|
|
the query, it will be performed in the foreground.
|
|
|
|
This is useful for queries that can be performed long enough before their result will be
|
|
needed, or for controllers which need to perform several independent queries.
|
|
|
|
```ruby
|
|
def index
|
|
@categories = Category.some_complex_scope.load_async
|
|
@posts = Post.some_complex_scope.load_async
|
|
end
|
|
```
|
|
|
|
*Jean Boussier*
|
|
|
|
* Implemented `ActiveRecord::Relation#excluding` method.
|
|
|
|
This method excludes the specified record (or collection of records) from
|
|
the resulting relation:
|
|
|
|
```ruby
|
|
Post.excluding(post)
|
|
Post.excluding(post_one, post_two)
|
|
```
|
|
|
|
Also works on associations:
|
|
|
|
```ruby
|
|
post.comments.excluding(comment)
|
|
post.comments.excluding(comment_one, comment_two)
|
|
```
|
|
|
|
This is short-hand for `Post.where.not(id: post.id)` (for a single record)
|
|
and `Post.where.not(id: [post_one.id, post_two.id])` (for a collection).
|
|
|
|
*Glen Crawford*
|
|
|
|
* Skip optimised #exist? query when #include? is called on a relation
|
|
with a having clause
|
|
|
|
Relations that have aliased select values AND a having clause that
|
|
references an aliased select value would generate an error when
|
|
#include? was called, due to an optimisation that would generate
|
|
call #exists? on the relation instead, which effectively alters
|
|
the select values of the query (and thus removes the aliased select
|
|
values), but leaves the having clause intact. Because the having
|
|
clause is then referencing an aliased column that is no longer
|
|
present in the simplified query, an ActiveRecord::InvalidStatement
|
|
error was raised.
|
|
|
|
A sample query affected by this problem:
|
|
|
|
```ruby
|
|
Author.select('COUNT(*) as total_posts', 'authors.*')
|
|
.joins(:posts)
|
|
.group(:id)
|
|
.having('total_posts > 2')
|
|
.include?(Author.first)
|
|
```
|
|
|
|
This change adds an addition check to the condition that skips the
|
|
simplified #exists? query, which simply checks for the presence of
|
|
a having clause.
|
|
|
|
Fixes #41417
|
|
|
|
*Michael Smart*
|
|
|
|
* Increment postgres prepared statement counter before making a prepared statement, so if the statement is aborted
|
|
without Rails knowledge (e.g., if app gets killed during long-running query or due to Rack::Timeout), app won't end
|
|
up in perpetual crash state for being inconsistent with Postgres.
|
|
|
|
*wbharding*, *Martin Tepper*
|
|
|
|
* Add ability to apply `scoping` to `all_queries`.
|
|
|
|
Some applications may want to use the `scoping` method but previously it only
|
|
worked on certain types of queries. This change allows the `scoping` method to apply
|
|
to all queries for a model in a block.
|
|
|
|
```ruby
|
|
Post.where(blog_id: post.blog_id).scoping(all_queries: true) do
|
|
post.update(title: "a post title") # adds `posts.blog_id = 1` to the query
|
|
end
|
|
```
|
|
|
|
*Eileen M. Uchitelle*
|
|
|
|
* `ActiveRecord::Calculations.calculate` called with `:average`
|
|
(aliased as `ActiveRecord::Calculations.average`) will now use column based
|
|
type casting. This means that floating-point number columns will now be
|
|
aggregated as `Float` and decimal columns will be aggregated as `BigDecimal`.
|
|
|
|
Integers are handled as a special case returning `BigDecimal` always
|
|
(this was the case before already).
|
|
|
|
```ruby
|
|
# With the following schema:
|
|
create_table "measurements" do |t|
|
|
t.float "temperature"
|
|
end
|
|
|
|
# Before:
|
|
Measurement.average(:temperature).class
|
|
# => BigDecimal
|
|
|
|
# After:
|
|
Measurement.average(:temperature).class
|
|
# => Float
|
|
```
|
|
|
|
Before this change, Rails just called `to_d` on average aggregates from the
|
|
database adapter. This is not the case anymore. If you relied on that kind
|
|
of magic, you now need to register your own `ActiveRecord::Type`
|
|
(see `ActiveRecord::Attributes::ClassMethods` for documentation).
|
|
|
|
*Josua Schmid*
|
|
|
|
* PostgreSQL: introduce `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type`
|
|
|
|
This setting controls what native type Active Record should use when you call `datetime` in
|
|
a migration or schema. It takes a symbol which must correspond to one of the configured
|
|
`NATIVE_DATABASE_TYPES`. The default is `:timestamp`, meaning `t.datetime` in a migration
|
|
will create a "timestamp without time zone" column. To use "timestamp with time zone",
|
|
change this to `:timestamptz` in an initializer.
|
|
|
|
You should run `bin/rails db:migrate` to rebuild your schema.rb if you change this.
|
|
|
|
*Alex Ghiculescu*
|
|
|
|
* PostgreSQL: handle `timestamp with time zone` columns correctly in `schema.rb`.
|
|
|
|
Previously they dumped as `t.datetime :column_name`, now they dump as `t.timestamptz :column_name`,
|
|
and are created as `timestamptz` columns when the schema is loaded.
|
|
|
|
*Alex Ghiculescu*
|
|
|
|
* Removing trailing whitespace when matching columns in
|
|
`ActiveRecord::Sanitization.disallow_raw_sql!`.
|
|
|
|
*Gannon McGibbon*, *Adrian Hirt*
|
|
|
|
* Expose a way for applications to set a `primary_abstract_class`
|
|
|
|
Multiple database applications that use a primary abstract class that is not
|
|
named `ApplicationRecord` can now set a specific class to be the `primary_abstract_class`.
|
|
|
|
```ruby
|
|
class PrimaryApplicationRecord
|
|
self.primary_abstract_class
|
|
end
|
|
```
|
|
|
|
When an application boots it automatically connects to the primary or first database in the
|
|
database configuration file. In a multiple database application that then call `connects_to`
|
|
needs to know that the default connection is the same as the `ApplicationRecord` connection.
|
|
However, some applications have a differently named `ApplicationRecord`. This prevents Active
|
|
Record from opening duplicate connections to the same database.
|
|
|
|
*Eileen M. Uchitelle*, *John Crepezzi*
|
|
|
|
* Support hash config for `structure_dump_flags` and `structure_load_flags` flags
|
|
Now that Active Record supports multiple databases configuration
|
|
we need a way to pass specific flags for dump/load databases since
|
|
the options are not the same for different adapters.
|
|
We can use in the original way:
|
|
|
|
```ruby
|
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = ['--no-defaults', '--skip-add-drop-table']
|
|
#or
|
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = '--no-defaults --skip-add-drop-table'
|
|
```
|
|
|
|
And also use it passing a hash, with one or more keys, where the key
|
|
is the adapter
|
|
|
|
```ruby
|
|
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
|
|
mysql2: ['--no-defaults', '--skip-add-drop-table'],
|
|
postgres: '--no-tablespaces'
|
|
}
|
|
```
|
|
|
|
*Gustavo Gonzalez*
|
|
|
|
* Connection specification now passes the "url" key as a configuration for the
|
|
adapter if the "url" protocol is "jdbc", "http", or "https". Previously only
|
|
urls with the "jdbc" prefix were passed to the Active Record Adapter, others
|
|
are assumed to be adapter specification urls.
|
|
|
|
Fixes #41137.
|
|
|
|
*Jonathan Bracy*
|
|
|
|
* Allow to opt-out of `strict_loading` mode on a per-record base.
|
|
|
|
This is useful when strict loading is enabled application wide or on a
|
|
model level.
|
|
|
|
```ruby
|
|
class User < ApplicationRecord
|
|
has_many :bookmarks
|
|
has_many :articles, strict_loading: true
|
|
end
|
|
|
|
user = User.first
|
|
user.articles # => ActiveRecord::StrictLoadingViolationError
|
|
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
|
|
|
user.strict_loading!(true) # => true
|
|
user.bookmarks # => ActiveRecord::StrictLoadingViolationError
|
|
|
|
user.strict_loading!(false) # => false
|
|
user.bookmarks # => #<ActiveRecord::Associations::CollectionProxy>
|
|
user.articles.strict_loading!(false) # => #<ActiveRecord::Associations::CollectionProxy>
|
|
```
|
|
|
|
*Ayrton De Craene*
|
|
|
|
* Add `FinderMethods#sole` and `#find_sole_by` to find and assert the
|
|
presence of exactly one record.
|
|
|
|
Used when you need a single row, but also want to assert that there aren't
|
|
multiple rows matching the condition; especially for when database
|
|
constraints aren't enough or are impractical.
|
|
|
|
```ruby
|
|
Product.where(["price = %?", price]).sole
|
|
# => ActiveRecord::RecordNotFound (if no Product with given price)
|
|
# => #<Product ...> (if one Product with given price)
|
|
# => ActiveRecord::SoleRecordExceeded (if more than one Product with given price)
|
|
|
|
user.api_keys.find_sole_by(key: key)
|
|
# as above
|
|
```
|
|
|
|
*Asherah Connor*
|
|
|
|
* Makes `ActiveRecord::AttributeMethods::Query` respect the getter overrides defined in the model.
|
|
|
|
Before:
|
|
|
|
```ruby
|
|
class User
|
|
def admin
|
|
false # Overriding the getter to always return false
|
|
end
|
|
end
|
|
|
|
user = User.first
|
|
user.update(admin: true)
|
|
|
|
user.admin # false (as expected, due to the getter overwrite)
|
|
user.admin? # true (not expected, returned the DB column value)
|
|
```
|
|
|
|
After this commit, `user.admin?` above returns false, as expected.
|
|
|
|
Fixes #40771.
|
|
|
|
*Felipe*
|
|
|
|
* Allow delegated_type to be specified primary_key and foreign_key.
|
|
|
|
Since delegated_type assumes that the foreign_key ends with `_id`,
|
|
`singular_id` defined by it does not work when the foreign_key does
|
|
not end with `id`. This change fixes it by taking into account
|
|
`primary_key` and `foreign_key` in the options.
|
|
|
|
*Ryota Egusa*
|
|
|
|
* Expose an `invert_where` method that will invert all scope conditions.
|
|
|
|
```ruby
|
|
class User
|
|
scope :active, -> { where(accepted: true, locked: false) }
|
|
end
|
|
|
|
User.active
|
|
# ... WHERE `accepted` = 1 AND `locked` = 0
|
|
|
|
User.active.invert_where
|
|
# ... WHERE NOT (`accepted` = 1 AND `locked` = 0)
|
|
```
|
|
|
|
*Kevin Deisz*
|
|
|
|
* Restore possibility of passing `false` to :polymorphic option of `belongs_to`.
|
|
|
|
Previously, passing `false` would trigger the option validation logic
|
|
to throw an error saying :polymorphic would not be a valid option.
|
|
|
|
*glaszig*
|
|
|
|
* Remove deprecated `database` kwarg from `connected_to`.
|
|
|
|
*Eileen M. Uchitelle*, *John Crepezzi*
|
|
|
|
* Allow adding nonnamed expression indexes to be revertible.
|
|
|
|
Fixes #40732.
|
|
|
|
Previously, the following code would raise an error, when executed while rolling back,
|
|
and the index name should be specified explicitly. Now, the index name is inferred
|
|
automatically.
|
|
```ruby
|
|
add_index(:items, "to_tsvector('english', description)")
|
|
```
|
|
|
|
*fatkodima*
|
|
|
|
* Only warn about negative enums if a positive form that would cause conflicts exists.
|
|
|
|
Fixes #39065.
|
|
|
|
*Alex Ghiculescu*
|
|
|
|
* Add option to run `default_scope` on all queries.
|
|
|
|
Previously, a `default_scope` would only run on select or insert queries. In some cases, like non-Rails tenant sharding solutions, it may be desirable to run `default_scope` on all queries in order to ensure queries are including a foreign key for the shard (i.e. `blog_id`).
|
|
|
|
Now applications can add an option to run on all queries including select, insert, delete, and update by adding an `all_queries` option to the default scope definition.
|
|
|
|
```ruby
|
|
class Article < ApplicationRecord
|
|
default_scope -> { where(blog_id: Current.blog.id) }, all_queries: true
|
|
end
|
|
```
|
|
|
|
*Eileen M. Uchitelle*
|
|
|
|
* Add `where.associated` to check for the presence of an association.
|
|
|
|
```ruby
|
|
# Before:
|
|
account.users.joins(:contact).where.not(contact_id: nil)
|
|
|
|
# After:
|
|
account.users.where.associated(:contact)
|
|
```
|
|
|
|
Also mirrors `where.missing`.
|
|
|
|
*Kasper Timm Hansen*
|
|
|
|
* Allow constructors (`build_association` and `create_association`) on
|
|
`has_one :through` associations.
|
|
|
|
*Santiago Perez Perret*
|
|
|
|
|
|
Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activerecord/CHANGELOG.md) for previous changes.
|