Skip to content

Conversation

@fatkodima
Copy link
Member

Closes #47593.

# Assuming "carts" table has "(shop_id, id)" as a primary key. add_foreign_key(:orders, :carts, primary_key: [:shop_id, :id]) # or add_foreign_key(:orders, :carts, column: [:cart_shop_id, :cart_id]) remove_foreign_key(:orders, :carts, primary_key: [:shop_id, :id]) foreign_key_exists?(:orders, :carts, primary_key: [:shop_id, :id])

We discussed 3 possible ways of using add_foreign_key.

The first one (add_foreign_key :brochures, :cars) (no :column and :primary_key options) turned out to be complex to implement, as it introduced a lot of kinda ugly changes in many places because we needed to properly generate these column names (consider configured table name prefixes and suffixes, pass a connection around to be able to query a primary key for the to_table. Some classes, like ForeignKeyDefinition does not have access to the connection, and so we needed to calculate these columns at several places differently and pass there).

And the biggest problem is when we need to add a foreign key for a self referencing tables, like

@connection.create_table :testings do |t|
t.references :parent1, foreign_key: { to_table: :testing_parents }
t.references :parent2, foreign_key: { to_table: :testing_parents }
t.references :self_join, foreign_key: { to_table: :testings }
end
That would produce very not elegant code.

So I made that it is required to pass at least one of :column or :primary_key options, as it is easy to infer one from the other.

cc @eileencodes @nvasilevski

@fatkodima fatkodima force-pushed the composite-foreign-keys branch 3 times, most recently from a277972 to ceaf183 Compare March 11, 2023 01:45
Copy link
Member

@eileencodes eileencodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @fatkodima thanks for working on this! I've left some comments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# # Assuming "carts" table has "(shop_id, id)" as a primary key.
# Assuming "carts" table has "(shop_id, id)" as a primary key.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are actually going to discourage using id as one of the ids in the composite key when we write the docs so can we change this to something like (shop_id, oid)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super clear on why we need to support both, can we support just primary_key and simplify the code a bit?

@fatkodima fatkodima force-pushed the composite-foreign-keys branch from ceaf183 to 45f6015 Compare May 26, 2023 12:09
@fatkodima
Copy link
Member Author

@eileencodes Thanks for the review, addressed the feedback.

I initially added support for both :primary_key and :column to be able to specify either one and the other will be inferred. Small convenience. But yeah, changed to require passing a :primary_key manually, if the :column is passed as an array.

@eileencodes eileencodes self-assigned this Sep 7, 2023
@eileencodes eileencodes added this to the 7.1.0 milestone Sep 7, 2023
@rafaelfranca rafaelfranca force-pushed the composite-foreign-keys branch from 45f6015 to 3f17465 Compare September 9, 2023 20:24
We only set the column to a single column if the primary key is a single value, so move that code to an explicit else.
This method is internal so we can just always pass the argument.
@rafaelfranca rafaelfranca merged commit 1559fe1 into rails:main Sep 9, 2023
alpaca-tc added a commit to alpaca-tc/ridgepole that referenced this pull request Oct 11, 2023
y-yagi added a commit to y-yagi/ridgepole that referenced this pull request Oct 13, 2023
alpaca-tc added a commit to alpaca-tc/ridgepole that referenced this pull request Oct 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

3 participants