There are valid use cases for running SQLite in production, however it must be done
with care, so instead of a warning most users won't see anyway, it's preferable to
leave the configuration commented out to force them to think about having the database
on a persistent volume etc.
Co-Authored-By: Jacopo Beschi <beschi.jacopo@gmail.com>
Fix: https://github.com/rails/rails/issues/50368
When called on a scope it would go through the default scoping
delegator that applies a default scope, which make no sense.
I checked https://github.com/rails/rails/issues/50327 and noticed that
clear API docs are needed. Some developers are using these methods
incorrectly, thinking they're only for Active Record Relation, but they
actually work with Enumerable.
Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.
This adds support for those to the SQLite3 adapter.
```ruby
create_table :users do |t|
t.string :name
t.virtual :name_upper, type: :string, as: 'UPPER(name)'
t.virtual :name_lower, type: :string, as: 'LOWER(name)', stored: true
end
```
Follow-up to #50281
I think `assert_queries` and `assert_no_queries` are so useful that I
want to read the documentation for the assertions. This patch adds the
doc for them and updated the test case named `test_assert_queries` to
verify `:matcher` works as expected.
I also changed `assert_queries` to make sure the subscriber of
`"sql.active_record"` is unsubscribed without affecting other test
cases. Without this change, some test cases fail because of execution of
`String#match`, which may cause `ArgumentError: invalid byte sequence in UTF-8`.
When preloading a has_many association, we were simply concatenating
the preloaded records without regard to whether they were already
loaded on the owner. Even though there is a check for `loaded?` in this
part of the preloader, some persisted records may not be marked as such.
For example, if a record is created via `owner.association.create`. This
change reverts to the previous behavior of replacing the target
association while also preserving non-persisted records, which was the
goal of https://github.com/rails/rails/pull/50129.
Co-authored-by: John Hawthorn <john@hawthorn.email>
Contrary to mysql2, trilogy will ignore the `socket` config
if `host` is set.
This makes it impossible to configure a UNIX domain socket connection
via `DATABASE_URL`, as the URL must include a host.
To assert the expected number of queries are made, Rails internally uses
`assert_queries` and `assert_no_queries`. These assertions can be
useful in applications as well.
By extracting these assertions to a module, the assertions can be
included where required.
These assertions are added to `ActiveSupport::TestCase` when
ActiveRecord is defined.
ActiveStorage, ActionView and ActionText are using this module now as
well, instead of duplicating the implementation.
The internal ActiveRecord::TestCase, used for testing ActiveRecord,
implements these assertions as well. However, these are slighlty more
advanced/complex and use the SQLCounter class. To keep things simple,
for now this implementation isn't used.
Add guidance to the Association Basics and `.belongs_to` method
documentation to encourage the renaming of a model's Ruby class to
coincide with updates to the existing data in the database.
Since Action Text and Active Storage rely on polymorphic associations,
add similar warnings to their guides.
Co-authored-by: Petrik de Heus <petrik@deheus.net>
Co-authored-by: Stephen Hanson <s.hanson5@gmail.com>
Co-authored-by: zzak <zzakscott@gmail.com>
Follow-up to #49146
The original behavior of `has_secure_token` was to use the
`send("#{attribute}=", some_value)` method so that the setter method, if
defined, was called. PR #49146 replaced the `send` method with
`write_attribute` which doesn't call the setter method and breaks
existing applications.
When set, validates that the timestamp prefix for a migration is in the form YYYYMMDDHHMMSS.
This is designed to prevent migration timestamps from being modified by hand.
It is turned off by default.
Fixes#50160
The `object_id` name may be used by polymorphic relations where `object` is the best name, like `notification.object`.
In that case two columns are created: `object_id` and `object_type`.
Update tests and comments to reference `__id__` instead of `object_id` for consistency.
When we reap connections, we check if they are inactive (connected and
responding to ping in most adapters) and if so we remove the connection
instead of checking it back in.
However, in acquire_connection, we weren't checking after reaping
whether we were allowed to build a new connection, only whether an
existing one was in the available pool.
This still leaves a race condition where if the background reaper thread
runs while a thread is polling and finds a free inactive connection, it
could have the same issue and not wake the waiting thread. However we
don't really expect the reaper to solve this (it only runs every 60
seconds by default, far too slow to solve for a blocked thread). I think
this should be fixed, just separately.
> Sometimes, operations on Times returns just float numbers of seconds, so, we
need to handle that.
> Example: Time.current - (Time.current + 1.hour) # => -3600.000001776 (Float)
When this happens, it's possible to endup with a pretty large number of seconds,
making the ISO 8601 formatted duration to trigger an `interval field value out
range error`.
PostgreSQL 15 has already improved overflow detection when casting values to
interval
However, to further reduce the likelihood of such issues and ensure
better-formatted duration types, it now implements the construction of
`ActiveSupport::Duration` during the serialization step.
How to reproduce (at least in versions prior to PG 15+):
``` ruby
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails", branch: "main"
gem "pg"
end
require "active_record"
require "minitest/autorun"
require "logger"
ActiveRecord::Base.establish_connection(
adapter: 'postgresql',
database: 'postgres',
username: 'postgres',
host: 'localhost'
)
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :projects, force: true do |t|
t.interval :duration
end
end
class Project < ActiveRecord::Base; end
class IntervalBugTest < Minitest::Test
def test_duration
project = Project.create(duration: 70.years)
assert_equal 70.years, project.duration
end
def test_duration_error
duration = 70.years.ago - Time.now()
assert_raises ActiveRecord::StatementInvalid do
Project.create(duration: duration)
end
end
end
```