1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #37905 from Vasfed/feature/guide_association_cleanup

Clarify that belongs_to is not always a one-to-one relation [ci skip]
This commit is contained in:
Jonathan Hefner 2020-05-07 00:12:34 -05:00 committed by GitHub
commit 7cd59448ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -86,7 +86,7 @@ In the remainder of this guide, you'll learn how to declare and use the various
### The `belongs_to` Association
A `belongs_to` association sets up a one-to-one connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model. For example, if your application includes authors and books, and each book can be assigned to exactly one author, you'd declare the book model this way:
A `belongs_to` association sets up a connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model. For example, if your application includes authors and books, and each book can be assigned to exactly one author, you'd declare the book model this way:
```ruby
class Book < ApplicationRecord
@ -117,9 +117,23 @@ class CreateBooks < ActiveRecord::Migration[6.0]
end
```
When used alone, `belongs_to` produces a one-directional one-to-one connection. Therefore each book in the above example "knows" its author, but the authors don't know about their books.
To setup a [bi-directional association](#bi-directional-associations) - use `belongs_to` in combination with a `has_one` or `has_many` on the other model.
`belongs_to` does not ensure reference consistency, so depending on the use case, you might also need to add a database-level foreign key constraint on the reference column, like this:
```ruby
create_table :books do |t|
t.belongs_to :author, foreign_key: true
# ...
end
```
### The `has_one` Association
A `has_one` association also sets up a one-to-one connection with another model, but with somewhat different semantics (and consequences). This association indicates that each instance of a model contains or possesses one instance of another model. For example, if each supplier in your application has only one account, you'd declare the supplier model like this:
A `has_one` association indicates that one other model has a reference to this model. That model can be fetched through this association.
For example, if each supplier in your application has only one account, you'd declare the supplier model like this:
```ruby
class Supplier < ApplicationRecord
@ -127,6 +141,8 @@ class Supplier < ApplicationRecord
end
```
The main difference from `belongs_to` is that the link column `supplier_id` is located in the other table:
![has_one Association Diagram](images/association_basics/has_one.png)
The corresponding migration might look like this:
@ -159,9 +175,11 @@ create_table :accounts do |t|
end
```
This relation can be [bi-directional](#bi-directional-associations) when used in combination with `belongs_to` on the other model.
### The `has_many` Association
A `has_many` association indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a `belongs_to` association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing authors and books, the author model could be declared like this:
A `has_many` association is similar to `has_one`, but indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a `belongs_to` association. This association indicates that each instance of the model has zero or more instances of another model. For example, in an application containing authors and books, the author model could be declared like this:
```ruby
class Author < ApplicationRecord
@ -192,6 +210,16 @@ class CreateAuthors < ActiveRecord::Migration[6.0]
end
```
Depending on the use case, it's usually a good idea to create a non-unique index and optionally
a foreign key constraint on the author column for the books table:
```ruby
create_table :books do |t|
t.belongs_to :author, index: true, foreign_key: true
# ...
end
```
### The `has_many :through` Association
A `has_many :through` association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding _through_ a third model. For example, consider a medical practice where patients make appointments to see physicians. The relevant association declarations could look like this:
@ -783,7 +811,10 @@ The following sections give the details of each type of association, including t
### `belongs_to` Association Reference
The `belongs_to` association creates a one-to-one match with another model. In database terms, this association says that this class contains the foreign key. If the other class contains the foreign key, then you should use `has_one` instead.
In database terms, the `belongs_to` association says that this model's table contains a column which represents a reference to another table.
This can be used to set up one-to-one or one-to-many relations, depending on the setup.
If the table of the other class contains the reference in a one-to-one relation, then you should use `has_one` instead.
#### Methods Added by `belongs_to`