aboutsummaryrefslogtreecommitdiffstats
path: root/guides/source
diff options
context:
space:
mode:
authorDavid Sherline <davidsherline@users.noreply.github.com>2017-01-01 12:13:48 -0600
committerDavid Sherline <dsherline@lightspeedsystems.com>2017-01-03 09:10:36 -0600
commit186327f74a2723cc22e0facbf12f72346e538986 (patch)
treed4ab6b79e887ce43b398412de15081dd1430985b /guides/source
parente42cbb7d31db1774d16a158586c5577c7ad1427c (diff)
downloadrails-186327f74a2723cc22e0facbf12f72346e538986.tar.gz
rails-186327f74a2723cc22e0facbf12f72346e538986.tar.bz2
rails-186327f74a2723cc22e0facbf12f72346e538986.zip
Clarify Bi-directional Associations docs
Rails automatically finds bi-directional associations between models with well-named associations. However, when using non-standard naming, you have to use :inverse_of to explicitly tell Rails about the bi- directional association. With reference to #27516 [ci skip]
Diffstat (limited to 'guides/source')
-rw-r--r--guides/source/association_basics.md64
1 files changed, 41 insertions, 23 deletions
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md
index 03d3daecc8..6e68935f9b 100644
--- a/guides/source/association_basics.md
+++ b/guides/source/association_basics.md
@@ -709,55 +709,73 @@ class Book < ApplicationRecord
end
```
-By default, Active Record doesn't know about the connection between these associations. This can lead to two copies of an object getting out of sync:
+Active Record will attempt to automatically identify that these two models share a bi-directional association based on the association name. In this way, Active Record will only load one copy of the `Author` object, making your application more efficient and preventing inconsistent data:
```ruby
a = Author.first
b = a.books.first
a.first_name == b.author.first_name # => true
-a.first_name = 'Manny'
-a.first_name == b.author.first_name # => false
+a.first_name = 'David'
+a.first_name == b.author.first_name # => true
```
-This happens because `a` and `b.author` are two different in-memory representations of the same data, and neither one is automatically refreshed from changes to the other. Active Record provides the `:inverse_of` option so that you can inform it of these relations:
+Active Record supports automatic identification for most associations with standard names. However, Active Record will not automatically identify bi-directional associations that contain any of the following options:
+
+* `:conditions`
+* `:through`
+* `:polymorphic`
+* `:class_name`
+* `:foreign_key`
+
+For example, consider the following model declarations:
```ruby
class Author < ApplicationRecord
- has_many :books, inverse_of: :author
+ has_many :books
end
class Book < ApplicationRecord
- belongs_to :author, inverse_of: :books
+ belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
end
```
-With these changes, Active Record will only load one copy of the author object, preventing inconsistencies and making your application more efficient:
+Active Record will no longer automatically recognize the bi-directional association:
```ruby
a = Author.first
b = a.books.first
-a.first_name == b.author.first_name # => true
-a.first_name = 'Manny'
-a.first_name == b.author.first_name # => true
+a.first_name == b.writer.first_name # => true
+a.first_name = 'David'
+a.first_name == b.writer.first_name # => false
+```
+
+Active Record provides the `:inverse_of` option so you can explicitly declare bi-directional associations:
+
+```ruby
+class Author < ApplicationRecord
+ has_many :books, inverse_of: 'writer'
+end
+
+class Book < ApplicationRecord
+ belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
+end
```
-There are a few limitations to `inverse_of` support:
+By including the `:inverse_of` option in the `has_many` association declaration, Active Record will now recognize the bi-directional association:
+
+```ruby
+a = Author.first
+b = a.books.first
+a.first_name == b.writer.first_name # => true
+a.first_name = 'David'
+a.first_name == b.writer.first_name # => true
+```
+
+There are a few limitations to `:inverse_of` support:
* They do not work with `:through` associations.
* They do not work with `:polymorphic` associations.
* They do not work with `:as` associations.
-* For `belongs_to` associations, `has_many` inverse associations are ignored.
-
-Every association will attempt to automatically find the inverse association
-and set the `:inverse_of` option heuristically (based on the association name).
-Most associations with standard names will be supported. However, associations
-that contain the following options will not have their inverses set
-automatically:
-
-* `:conditions`
-* `:through`
-* `:polymorphic`
-* `:foreign_key`
Detailed Association Reference
------------------------------