diff options
Diffstat (limited to 'guides/source/association_basics.md')
-rw-r--r-- | guides/source/association_basics.md | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/guides/source/association_basics.md b/guides/source/association_basics.md index 65c8154064..16a5241319 100644 --- a/guides/source/association_basics.md +++ b/guides/source/association_basics.md @@ -572,7 +572,7 @@ end These need to be backed up by a migration to create the `assemblies_parts` table. This table should be created without a primary key: ```ruby -class CreateAssemblyPartJoinTable < ActiveRecord::Migration +class CreateAssembliesPartsJoinTable < ActiveRecord::Migration def change create_table :assemblies_parts, id: false do |t| t.integer :assembly_id @@ -693,6 +693,17 @@ There are a few limitations to `inverse_of` support: * 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 ------------------------------ @@ -1648,9 +1659,10 @@ The `select` method lets you override the SQL `SELECT` clause that is used to re WARNING: If you specify your own `select`, be sure to include the primary key and foreign key columns of the associated model. If you do not, Rails will throw an error. -##### `uniq` +##### `distinct` -Use the `uniq` method to keep the collection free of duplicates. This is mostly useful together with the `:through` option. +Use the `distinct` method to keep the collection free of duplicates. This is +mostly useful together with the `:through` option. ```ruby class Person < ActiveRecord::Base @@ -1666,14 +1678,15 @@ person.posts.inspect # => [#<Post id: 5, name: "a1">, #<Post id: 5, name: "a1">] Reading.all.inspect # => [#<Reading id: 12, person_id: 5, post_id: 5>, #<Reading id: 13, person_id: 5, post_id: 5>] ``` -In the above case there are two readings and `person.posts` brings out both of them even though these records are pointing to the same post. +In the above case there are two readings and `person.posts` brings out both of +them even though these records are pointing to the same post. -Now let's set `uniq`: +Now let's set `distinct`: ```ruby class Person has_many :readings - has_many :posts, -> { uniq }, through: :readings + has_many :posts, -> { distinct }, through: :readings end person = Person.create(name: 'Honda') @@ -1684,7 +1697,29 @@ person.posts.inspect # => [#<Post id: 7, name: "a1">] Reading.all.inspect # => [#<Reading id: 16, person_id: 7, post_id: 7>, #<Reading id: 17, person_id: 7, post_id: 7>] ``` -In the above case there are still two readings. However `person.posts` shows only one post because the collection loads only unique records. +In the above case there are still two readings. However `person.posts` shows +only one post because the collection loads only unique records. + +If you want to make sure that, upon insertion, all of the records in the +persisted association are distinct (so that you can be sure that when you +inspect the association that you will never find duplicate records), you should +add a unique index on the table itself. For example, if you have a table named +``person_posts`` and you want to make sure all the posts are unique, you could +add the following in a migration: + +```ruby +add_index :person_posts, :post, :unique => true +``` + +Note that checking for uniqueness using something like ``include?`` is subject +to race conditions. Do not attempt to use ``include?`` to enforce distinctness +in an association. For instance, using the post example from above, the +following code would be racy because multiple users could be attempting this +at the same time: + +```ruby +person.posts << post unless person.posts.include?(post) +``` #### When are Objects Saved? |