Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
b879079b
Commit
b879079b
authored
May 05, 2017
by
Yorick Peterse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add documentation about adding foreign keys
[ci skip]
parent
2e36ed66
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
68 additions
and
0 deletions
+68
-0
changelogs/unreleased/document-foreign-keys.yml
changelogs/unreleased/document-foreign-keys.yml
+4
-0
doc/development/README.md
doc/development/README.md
+1
-0
doc/development/foreign_keys.md
doc/development/foreign_keys.md
+63
-0
No files found.
changelogs/unreleased/document-foreign-keys.yml
0 → 100644
View file @
b879079b
---
title
:
Add documentation about adding foreign keys
merge_request
:
author
:
doc/development/README.md
View file @
b879079b
...
@@ -48,6 +48,7 @@
...
@@ -48,6 +48,7 @@
-
[
What requires downtime?
](
what_requires_downtime.md
)
-
[
What requires downtime?
](
what_requires_downtime.md
)
-
[
Adding database indexes
](
adding_database_indexes.md
)
-
[
Adding database indexes
](
adding_database_indexes.md
)
-
[
Post Deployment Migrations
](
post_deployment_migrations.md
)
-
[
Post Deployment Migrations
](
post_deployment_migrations.md
)
-
[
Foreign Keys & Associations
](
foreign_keys.md
)
## Compliance
## Compliance
...
...
doc/development/foreign_keys.md
0 → 100644
View file @
b879079b
# Foreign Keys & Associations
When adding an association to a model you must also add a foreign key. For
example, say you have the following model:
```
ruby
class
User
<
ActiveRecord
::
Base
has_many
:posts
end
```
Here you will need to add a foreign key on column
`posts.user_id`
. This ensures
that data consistency is enforced on database level. Foreign keys also mean that
the database can very quickly remove associated data (e.g. when removing a
user), instead of Rails having to do this.
## Adding Foreign Keys In Migrations
Foreign keys can be added concurrently using
`add_concurrent_foreign_key`
as
defined in
`Gitlab::Database::MigrationHelpers`
. See the
[
Migration Style
Guide
](
migration_style_guide.md
)
for more information.
Keep in mind that you can only safely add foreign keys to existing tables after
you have removed any orphaned rows. The method
`add_concurrent_foreign_key`
does not take care of this so you'll need to do so manually.
## Cascading Deletes
Every foreign key must define an
`ON DELETE`
clause, and in 99% of the cases
this should be set to
`CASCADE`
.
## Indexes
When adding a foreign key in PostgreSQL the column is not indexed automatically,
thus you must also add a concurrent index. Not doing so will result in cascading
deletes being very slow.
## Dependent Removals
Don't define options such as
`dependent: :destroy`
or
`dependent: :delete`
when
defining an association. Defining these options means Rails will handle the
removal of data, instead of letting the database handle this in the most
efficient way possible.
In other words, this is bad and should be avoided at all costs:
```
ruby
class
User
<
ActiveRecord
::
Base
has_many
:posts
,
dependent: :destroy
end
```
Should you truly have a need for this it should be approved by a database
specialist first.
You should also not define any
`before_destroy`
or
`after_destroy`
callbacks on
your models _unless_ absolutely required and only when approved by database
specialists. For example, if each row in a table has a corresponding file on a
file system it may be tempting to add a
`after_destroy`
hook. This however
introduces non database logic to a model, and means we can no longer rely on
foreign keys to remove the data as this would result in the filesystem data
being left behind. In such a case you should use a service class instead that
takes care of removing non database data.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment