diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2017-01-03 13:45:03 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-03 13:45:03 -0500 |
commit | 2a7fcdad18e043b141eb2abe37bd5f241ca9c8c7 (patch) | |
tree | 0d3bc067acde0a871e50027af8f947873a456adb | |
parent | 929ded40fc1bdeb42353868b7ada9e73615ad4b4 (diff) | |
parent | 186327f74a2723cc22e0facbf12f72346e538986 (diff) | |
download | rails-2a7fcdad18e043b141eb2abe37bd5f241ca9c8c7.tar.gz rails-2a7fcdad18e043b141eb2abe37bd5f241ca9c8c7.tar.bz2 rails-2a7fcdad18e043b141eb2abe37bd5f241ca9c8c7.zip |
Merge pull request #27538 from davidsherline/guides-bi-dir-associations
Clarify Bi-directional Associations docs
-rw-r--r-- | guides/source/association_basics.md | 64 |
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 ------------------------------ |