Fix: https://github.com/rails/rails/issues/42983
The usefulness of these timestamps is a bit questionable,
but I suppose they could be useful for debugging, and
removing them would require to ship a migration etc.
Since `record_timestamps` is now a `class_attribute` we
can simply force it to `true` in just that class.
Without classic, this test would be testing that Zeitwerk works. That
belongs to the test suite of Zeitwerk.
Active Record has the class available, whether it was already loaded or
pending autoloading, is not AR's concern.
This commit addresses CI failure of Active Record isolation tests.
https://buildkite.com/rails/rails/builds/79936
Follow up #41392
* Steps to reproduce
```ruby
$ cd activerecord
$ bin/test test/cases/associations/belongs_to_associations_test.rb test/cases/associations/has_many_associations_test.rb test/cases/associations/has_many_through_disable_joins_associations_test.rb test/cases/associations/has_one_associations_test.rb test/cases/connection_adapters/schema_cache_test.rb test/cases/inheritance_test.rb test/cases/migration_test.rb test/cases/store_test.rb test/cases/strict_loading_test.rb
```
Since the entire output is too long, here is the minimum case fixed by
this commit.
```ruby
$ cd activerecord
$ bin/test test/cases/associations/belongs_to_associations_test.rb:38
Using sqlite3
Run options: --seed 34180
E
Error:
BelongsToAssociationsTest#test_belongs_to:
NameError: Rails couldn't find a valid model for Club association. Please provide the :class_name option on the association declaration. If :class_name is already provided, make sure it's an ActiveRecord::Base subclass.
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/reflection.rb:431:in `rescue in compute_class'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/reflection.rb:422:in `compute_class'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/reflection.rb:372:in `klass'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/reflection.rb:722:in `association_primary_key'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/reflection.rb:727:in `join_primary_key'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_row.rb:150:in `block in resolve_sti_reflections'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_row.rb:138:in `each_value'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_row.rb:138:in `resolve_sti_reflections'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_row.rb:92:in `fill_row_model_attributes'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_row.rb:70:in `initialize'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_rows.rb:36:in `new'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_rows.rb:36:in `block in build_table_rows_from'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_rows.rb:35:in `each'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_rows.rb:35:in `map'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_rows.rb:35:in `build_table_rows_from'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixture_set/table_rows.rb:18:in `initialize'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:692:in `new'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:692:in `table_rows'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:633:in `block (2 levels) in insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:632:in `each'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:632:in `block in insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:629:in `each'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:629:in `insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:615:in `read_and_insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:567:in `create_fixtures'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/test_fixtures.rb:268:in `load_fixtures'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/test_fixtures.rb:122:in `setup_fixtures'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/test_fixtures.rb:10:in `before_setup'
bin/test test/cases/associations/belongs_to_associations_test.rb:38
Finished in 0.083668s, 11.9520 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
$
```
When an engine's migration is installed in a rails application, a
comment is inserted after any magic comments indicating the migration's
source. However, the current implementation does not take into
account whether there is an empty line after magic comments, and the
generated migration will not pass rubocop's
Layout/EmptyLineAfterMagicComment even if the engine's migration did.
This commit changes the implementation to insert the new comment after
a newline occuring after magic comments, if it exists.
Example Engine Migration:
```ruby
# frozen_string_literal: true
# coding: ISO-8859-15
class CurrenciesHaveSymbols < ActiveRecord::Migration::Current
end
```
Before change:
```ruby
# frozen_string_literal: true
# coding: ISO-8859-15
# This migration comes from bukkits (originally 1)
class CurrenciesHaveSymbols < ActiveRecord::Migration::Current
end
```
After change:
```ruby
# frozen_string_literal: true
# coding: ISO-8859-15
# This migration comes from bukkits (originally 1)
class CurrenciesHaveSymbols < ActiveRecord::Migration::Current
end
```
This allows you to specify an explicit order that you'd like records
returned in based on a SQL expression. By default, this will be accomplished
using a case statement, as in:
```ruby
Post.in_order_of(:id, [3, 5, 1])
```
will generate the SQL:
```sql
SELECT "posts".* FROM "posts" ORDER BY CASE "posts"."id" WHEN 3 THEN 1 WHEN 5 THEN 2 WHEN 1 THEN 3 ELSE 4 END ASC
```
However, because this functionality is built into MySQL in the form of the
`FIELD` function, that connection adapter will generate the following SQL
instead:
```sql
SELECT "posts".* FROM "posts" ORDER BY FIELD("posts"."id", 1, 5, 3) DESC
```
*Kevin Newton*
The language in the docs is clearer without saying MySQL is stupid. The
test doesn't need stupid in the value to be used - an incorrect value is
incorrect.
This comment was correct when it was added in 65843e1. In that commit, ActiveRecord::AssociationScope#scope applies the nearest association's scope, and #add_constraints skips it.
c8d8899 made the comment incorrect. It modified #scope not to apply the nearest association's scope and #add_constraints to apply scopes for the entire association chain.
Managed to reproduce CI failure at https://buildkite.com/rails/rails/builds/79496#0c03f856-9be1-4ca0-88c9-e1df21ae0a07
This commitaddresses the following errors by loading :author_addresses fixture because
`:authors` has a foreign key to `:author_addresses`.
* sqlite3 adapter
```ruby
$ bin/test test/cases/adapters/sqlite3/explain_test.rb test/cases/fixtures_test.rb -n "/^(?:SQLite3ExplainTest#(?:test_explain_with_eager_loading)|FixturesWithForeignKeyViolationsTest#(?:test_does_not_raise_if_no_fk_violations))$/" --seed 2529
Using sqlite3
Run options: -n "/^(?:SQLite3ExplainTest#(?:test_explain_with_eager_loading)|FixturesWithForeignKeyViolationsTest#(?:test_does_not_raise_if_no_fk_violations))$/" --seed 2529
.E
Error:
FixturesWithForeignKeyViolationsTest#test_does_not_raise_if_no_fk_violations:
RuntimeError: Foreign key violations found in your fixture data. Ensure you aren't referring to labels that don't exist on associations.
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:641:in `block in insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:629:in `each'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:629:in `insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:615:in `read_and_insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:567:in `create_fixtures'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:844:in `block (2 levels) in test_does_not_raise_if_no_fk_violations'
/home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/testing/assertions.rb:34:in `assert_nothing_raised'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:843:in `block in test_does_not_raise_if_no_fk_violations'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:857:in `with_verify_foreign_keys_for_fixtures'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:842:in `test_does_not_raise_if_no_fk_violations'
bin/test test/cases/fixtures_test.rb:835
Finished in 0.045767s, 43.6991 runs/s, 174.7966 assertions/s.
2 runs, 8 assertions, 0 failures, 1 errors, 0 skips
$
```
* postgresql adapter
```ruby
$ ARCONN=postgresql bin/test test/cases/adapters/postgresql/explain_test.rb test/cases/fixtures_test.rb -n "/^(?:PostgreSQLExplainTest#(?:test_explain_with_eager_loading)|FixturesWithForeignKeyViolationsTest#(?:test_does_not_raise_if_no_fk_violations))$/" --seed 16926
Using postgresql
Run options: -n "/^(?:PostgreSQLExplainTest#(?:test_explain_with_eager_loading)|FixturesWithForeignKeyViolationsTest#(?:test_does_not_raise_if_no_fk_violations))$/" --seed 16926
.E
Error:
FixturesWithForeignKeyViolationsTest#test_does_not_raise_if_no_fk_violations:
RuntimeError: Foreign key violations found in your fixture data. Ensure you aren't referring to labels that don't exist on associations.
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:641:in `block in insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:629:in `each'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:629:in `insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:615:in `read_and_insert'
/home/yahonda/src/github.com/rails/rails/activerecord/lib/active_record/fixtures.rb:567:in `create_fixtures'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:844:in `block (2 levels) in test_does_not_raise_if_no_fk_violations'
/home/yahonda/src/github.com/rails/rails/activesupport/lib/active_support/testing/assertions.rb:34:in `assert_nothing_raised'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:843:in `block in test_does_not_raise_if_no_fk_violations'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:857:in `with_verify_foreign_keys_for_fixtures'
/home/yahonda/src/github.com/rails/rails/activerecord/test/cases/fixtures_test.rb:842:in `test_does_not_raise_if_no_fk_violations'
bin/test test/cases/fixtures_test.rb:835
Finished in 0.121193s, 16.5027 runs/s, 49.5080 assertions/s.
2 runs, 6 assertions, 0 failures, 1 errors, 0 skips
$
```
* It does not reproduce with mysql2 adapter because MySQL does not have
features to validate existing foreign keys, but added
:author_addresses in Mysql2ExplainTest for consistency.
Follow up #42674
Permit checking whether a belongs_to association has been pointed to a new target record in the previous save and whether it will point to a new target record in the next save.
post.category # => #<Category id: 1, name: "Ruby">
post.category = Category.second # => #<Category id: 2, name: "Programming">
post.category_changed? # => true
post.category_previously_changed? # => false
post.save!
post.category_changed? # => false
post.category_previously_changed? # => true
Dumping the schema is on by default for all databases in an application. To turn it off for a
specific database use the `schema_dump` option:
```yaml
# config/database.yml
production:
schema_dump: false
```
Co-authored-by: Luis Vasconcellos <vasconcelloslf@gmail.com>