Commit Graph

17540 Commits

Author SHA1 Message Date
Aaron Harpole
aa909b2444 allow pre-7.1 migrations to use legacy index names with create_table
Previously, if you were using a pre-7.1 migration and you were adding an index using `create_table`, the index would be named using the new index naming functionality introduced in  #47753.
2023-04-04 15:42:47 -07:00
Steve Hill
ef14d13308 Correctly dump check constraints for MySQL 8.0.16+
If you're using MySQL 8.0.16+ and your database contains a table with
a check constraint, the first and last characters of the constraint
will be stripped when dumping the schema; this makes it impossible
to use check constraints in a MySQL 8.0 database with the `:ruby`
schema format; once dumped, they cannot be re-imported.

This is because, up until MySQL 8.0.16, all check constraints were
surrounded by an extra set of parentheses; this behaviour differed
from that presented by MariaDB, which handled them correctly thanks
to an engine check within the AbstractMySqlAdapter.

With this change, we only strip the parentheses if they are present,
which prevents the corruption of the constraint.

It is also possible that the exported check constraint will contain
invalid and unexpected whitespace characters; we handle that here too,
stripping out sequences of `\\` and `\n`, as well as any other
whitespace.
2023-04-04 18:30:42 +01:00
Eileen M. Uchitelle
502f0445d5
Merge pull request #47836 from Shopify/pm/cpk-relation-handler
Only default to select primary key when non-composite
2023-04-03 09:14:38 -04:00
Paarth Madan
e0e89b1441 Only default to select primary key when non-composite
When the relation being handled has no selected values, it fallsback to selecting the model's primary key. In composite key cases, this can lead to attempting to compare a single attribute to a list of attributes, which leads to malformed syntax at the SQL level. This check prevents any code from attempting to do so, by raising in CPK cases when defaulting to primary key. For now, users can build these queries themselves.
2023-03-31 15:02:59 -04:00
eileencodes
01c4605800
Fix autoincrement on primary key
MySQL adapters take an auto_increment option but when using a primary
key type that option is silently ignored and doesn't change behavior.
This fixes the issue by only applying `options[:auto_increment] = true`
if it wasn't set to false already.

I didn't make changes to the other adapters because they don't accept
`auto_increment` as an option. If we want this for postgres we'll need
to implement the option first.
2023-03-30 15:53:26 -04:00
Daniel Whitney
15369fd912
Infer foerign_key when inverse_of is present (#47797)
* Infer `foerign_key` when `inverse_of` is present

Automatically infer `foreign_key` on `has_one` and `has_many` associations when `inverse_of` is present.

When inverse of is present, rails has all the info it needs to figure out what the foreign_key on the associated model should be.  I can't imagine this breaking anything

* Update test models to remove redundant foreign_keys

* add changelog entry

* fix changelog grammar

Co-authored-by: Rafael Mendonça França <rafael@franca.dev>
2023-03-30 15:22:23 -04:00
Eileen M. Uchitelle
fc2b937d56
Merge pull request #47819 from Shopify/always-respect-explicitly-configured-query-constraints
Respect explicitly configured `query_constraints`
2023-03-30 11:59:05 -04:00
Nikita Vasilevsky
767cd52e76 Respect explicitly configured query_constraints 2023-03-30 15:15:46 +00:00
Petrik de Heus
dc0f20595d
Merge pull request #47717 from p8/docs/include-readmes
Include READMEs in main framework pages of the API documentation
2023-03-30 16:43:14 +02:00
Eileen M. Uchitelle
82fca55314
Merge pull request #47810 from Shopify/pm/fixture-id
Generate unique members of a composite key in fixtures
2023-03-30 08:57:02 -04:00
Jean Boussier
1d29f01ff5 Refactor Relation#none to no longer use Object#extend
Ref: https://github.com/rails/rails/pull/47314
Ref: https://bugs.ruby-lang.org/issues/19436

`Object#extend` is really bad for performance as it generate an
infinite amount of unique classes from the point of view of the Ruby
virtual machine, so it keeps invalidating call caches.

Additionally, these call caches keep a reference on the last instance
they saw, which may lead to what is essentially a memory leak.
2023-03-30 12:27:41 +02:00
Jean Boussier
80c51c1d2f
Merge pull request #47816 from Shopify/fix-relation-delegation
ActiveRecord::Delegation prevent overriding existing methods
2023-03-30 12:27:14 +02:00
Jean Boussier
e4009c8d66 ActiveRecord::Delegation prevent overriding existing methods
I discovered this while working on https://github.com/rails/rails/pull/47800

The bug is quite subtle.

If you call `Model.all.delete(id)`, `all` is an `ActiveRecord::Relation`
which does not respond to `delete`, so it delegates to `Model.delete`
and generate that method in the `GeneratedRelationMethods` module.

The problem however, is that `CollectionProxy` does define `delete`,
so after that initial call, the `Model::ActiveRecord_CollectionProxy`
subclass now has its `delete` method overridden, and now delegate
to the model.

Here I chose to keep that method generation caching, but I'm honestly
not convinced it's really needed. I question how much of a hotspot
these methods are, and we're busting method caches and generating
a lot of code to save on a minor `method_missing` call.

I think we should just remove that caching.
2023-03-30 11:52:53 +02:00
Paarth Madan
f7062f2676 Generate unique members of a composite key in fixtures
Typically, a fixture's label is hashed into a single unique identifier
that sufficiently represent the respective fixture. In composite key
models, there's still only one label, but a requirement to populate
values for an arbitrary number of columns. Until now, these columns
would all take on the same value, but these may appear odd to an end
user and lead to confusion. This commit uses the index of the column in
the composite key to shift the hash in a deterministic way. In this
case, we bit shift the hashed value index-times and modulo it with the
max. This differentiates components of the key enough that there doesn't
appear to be a correlation.
2023-03-29 20:00:49 -04:00
Eileen M. Uchitelle
b6c76826ff
Merge pull request #47796 from Shopify/pm/read-attribute
`#read_attribute(:id)` should always return the primary key
2023-03-29 08:56:49 -04:00
Matthew Draper
65115f731c
Merge pull request #47734 from olefriis/add-arel-node-docs-for-binding-parameters-and-plus
Add docs on Arel.sql binding parameters and +
2023-03-29 19:00:36 +10:30
Jean Boussier
59f2b06493 Use idx_ instead of ix_ for index prefix
Followup: #47753
2023-03-29 09:28:46 +02:00
Mike Coutermarsh
3682aa1016
Fix Rails generated index name being too long
This updates the index name generation to always create a valid index name if one is not passed by the user.

Set the limit to 62 bytes to ensure it works for the default configurations of Sqlite, mysql & postgres.

MySQL: 64
Postgres: 63
Sqlite: 62

When over the limit, we fallback to a "short format" that includes a hash to guarantee uniqueness in the generated index name.
2023-03-28 17:34:52 -04:00
Paarth Madan
1cd48342a4 #read_attribute(:id) should always return the primary key 2023-03-28 16:21:04 -04:00
eileencodes
0f6215a43b
Remove superflous check
We don't need this check, we just need the `id.first.is_a?(Array)`
check.
2023-03-28 14:54:26 -04:00
Eileen M. Uchitelle
d4377aa6e8
Merge pull request #47787 from Shopify/pm/cpk-destroy
Accept list of composite primary keys in #destroy
2023-03-28 14:50:21 -04:00
Paarth Madan
d8c4217a6f Accept list of composite primary keys in #destroy 2023-03-28 12:35:42 -04:00
Jean Boussier
dee93277e3 Implement marshal_dump and marshal_load on ActiveRecord::Base
Fix: https://github.com/rails/rails/issues/47704
Superseed: https://github.com/rails/rails/pull/47722

While the instance variable ordering bug will be fixed in Ruby 3.2.2,
it's not great that we're depending on such brittle implementation detail.

Additionally, Marshalling Active Record instances is currently very inefficient,
the payload include lots of redundant data that shouldn't make it into the cache.

In this new format the serialized payload only contains basic Ruby core or stdlib objects,
reducing the risk of changes in the internal representation of Rails classes.
2023-03-28 16:46:14 +02:00
fatkodima
142a5453d4 Fix dumping enum definitions from other schemas 2023-03-28 17:14:44 +03:00
Andrew Novoselac
a35a2d0d15 Fix an issue where TestFixtures#fixture_path was returning an array. It is deprecated, but it should still return a string until it is removed. So, if multiple fixture_paths are configured, it just returns the first path. 2023-03-24 15:42:24 -04:00
Eileen M. Uchitelle
995768e791
Merge pull request #47762 from Shopify/ar-calculations-ids-for-a-cpk-model
Fix `ActiveRecord::Calculations#ids` for a composite primary key model
2023-03-24 09:31:16 -04:00
Eileen M. Uchitelle
643b5a6c87
Merge pull request #47742 from Shopify/fix-query-constraints-association-from-a-non-query-constraints-model
Fix precedence of `primary_key:` in associations with `query_constraints`
2023-03-24 09:29:28 -04:00
Nikita Vasilevsky
1217127703 Fix ActiveRecord::Calculations#ids for a composite primary key model
Given a model with a composite primary key like:
`TravelRoute.primary_key = [:from, :to]`

Calling `TravelRoute.ids` would return an array of identifiers which is
represented by an array of arrays:

```ruby
TravelRoute.all.ids # => [["Ottawa", "New York"], ["London", "Paris"]]
```
2023-03-24 12:45:54 +00:00
Nikita Vasilevsky
f29ff0f0a0 Fix precedence of primary_key: in associations with query_constraints 2023-03-23 23:01:06 +00:00
Paarth Madan
996d5023f0 Support composite primary keys during transaction rollback 2023-03-22 19:16:05 -04:00
Eileen M. Uchitelle
2cef3ac45b
Merge pull request #47729 from Shopify/pm/cpk-where-syntax
Introduce query-by-tuple syntax
2023-03-22 17:08:42 -04:00
Vipul A M
047a76e37f
Merge pull request #47702 from shouichi/class-cache-nodoc
Add nodoc to ActiveRecord::FixtureSet::ClassCache [skip ci]
2023-03-23 01:54:01 +05:30
Paarth Madan
77b9cddbbe Use tuple query syntax to avoid branching 2023-03-22 13:56:48 -04:00
Paarth Madan
e39e013cf7 Specify where clauses by mapping columns to tuples
With the introduction of composite primary keys, a common usecase is querying for records with tuples representing the composite key. This change introduces new syntax to the where clause that allows specifying an array of columns mapped to a list of corresponding tuples. It converts this to an OR-joined list of separate queries, similar to previous implementations that rely on grouping queries.
2023-03-22 13:56:47 -04:00
Eileen M. Uchitelle
355fd59290
Merge pull request #47731 from Shopify/fix-CPK-models-equality
Fix `#hash` and `#==` for composite pk models
2023-03-22 10:28:45 -04:00
Nikita Vasilevsky
7b1a617c21 Fix #hash and #== for composite pk models
Given a model with a composite primary key, for example:
`TravelRoute.primary_key = [:from, :to]`

and two objects of the given model, objects `a` and `b`, should be
equal to each other and have the same `hash` value if they have the same
values for the composite primary key, like:

```ruby
a = TravelRoute.new(from: "NYC", to: "LAX")
b = TravelRoute.new(from: "NYC", to: "LAX")
a == b # => true

a.hash == b.hash # => true
```

At the same time, two objects of the given model should not be equal to
each other and should have different `hash` values if they have
different primary key values or no primary key being set, like:

```ruby
a = TravelRoute.new(from: "NYC", to: "LAX")
b = TravelRoute.new(from: "NYC", to: "SFO")
a == b # => false
a.hash == b.hash # => false

TravelRoute.new == TravelRoute.new # => false
TravelRoute.new.hash == TravelRoute.new.hash # => false
```
2023-03-22 13:46:20 +00:00
Ole Friis Østergaard
123c93a6ef Add docs on Arel.sql binding parameters and + 2023-03-22 11:19:51 +01:00
Petrik
7c94708d24 Include READMEs in main framework pages of the API documentation
Currently when opening the main framework pages there is no introduction
to the framework. Instead we only see a whole lot of modules and the
`gem_version` and `version` methods.

By including the READMEs using the `:include:` directive each frameworks
has a nice introduction.
For markdown READMEs we need to add the :markup: directive.

[ci-skip]

Co-authored-by: zzak <zzakscott@gmail.com>
2023-03-21 21:16:28 +01:00
Eileen M. Uchitelle
ba19dbc499
Merge pull request #47721 from Shopify/fix-nullifying-has-many-through-association
Fix nullification of has_many :through association with `query_constraints
2023-03-21 11:57:28 -04:00
Nikita Vasilevsky
300c853494 Fix nullification of has_many :through association with query_constraints
Given a `has_many :through` association with `query_constraints`:

```ruby
BlogPost.has_many :posts_tags
BlogPost.has_many :tags,
  through: :posts_tags,
  query_constraints: [:blog_id, :post_id]
``

It is possible to nullify the association like `blog_post.tags = []`
which results in deletion of records from the `posts_tags` joining table.
2023-03-21 13:51:30 +00:00
Eileen M. Uchitelle
4b183e4942
Merge pull request #47720 from Shopify/pm/cpk-id-accessor
Accept composite primary key in `id=`
2023-03-21 09:50:01 -04:00
Paarth Madan
10e86244ce Accept composite primary key in id= 2023-03-20 19:00:43 -04:00
Nick Borromeo
6bd100711c Allow SQL Warnings to be ignored using error codes
In https://github.com/rails/rails/pull/46690 the `db_warnings_action` and `db_warnings_ignore` configs where added. The
`db_warnings_ignore` can take a list of warning messages to match against.

At GitHub we have a subscriber that that does something like this but also filters out error codes. There might also be
other applications that filter via error codes and this could be something they can use instead of just the explicit
messages.

This also refactors the adapter tests in order for mysql2 and postgresql adapters to share the same helper when setting
the db_warnings_action and db_warnings_ignore configs
2023-03-20 13:06:22 -07:00
Matthew Draper
bc081a55be
Merge pull request #47715 from adrianna-chang-shopify/ac-pg-fix-conn-param
PostgreSQL adapter uses :host instead of :hostname for connection params
2023-03-21 04:27:38 +10:30
Adrianna Chang
b3d6c6496f
PostgreSQL adapter uses :host instead of :hostname for connection parameters 2023-03-20 13:09:10 -04:00
sampatbadhe
d9d8d8a4d2 Correct typos in activerecord changelog and querylogs docs [ci-skip] 2023-03-18 19:07:41 +05:30
Rafael Mendonça França
e23e1718ea
Merge pull request #47690 from andrewn617/add-on-load-callback-for-active-record-fixtures
Run a load hook when TestFixtures is included
2023-03-17 14:10:52 -04:00
Andrew Novoselac
49283adc16 Run a load hook when TestFixtures is included 2023-03-17 13:36:48 -04:00
Shouichi Kamiya
0ad120b72e Add nodoc to ActiveRecord::FixtureSet::ClassCache [skip ci]
I believe this is an implementation detail.
2023-03-17 15:21:05 +09:00
Nikita Vasilevsky
95a3e6cd0a Allow querying by whole record for composite query constraints associations
Given an association defined with composite query constraints like:
```ruby
BlogPost.has_many :comments, query_constraints: [:blog_id, :blog_post_id]
```

it is possible to query blog posts by whole `comments` objects like:

```ruby
comments = Comment.first(2)
BlogPost.where(comments: comments).to_a
```
2023-03-16 17:02:50 +00:00