diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index e13d1036f2a..bfb829ef9a1 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,19 @@ +* Infer `foerign_key` when `inverse_of` is present on `has_one` and `has_many` associations. + + ```ruby + has_many :citations, foreign_key: "book1_id", inverse_of: :book + ``` + + can be simplified to + + ```ruby + has_many :citations, inverse_of: :book + ``` + + and the foreign_key will be read from the corresponding `belongs_to` association. + + *Daniel Whitney* + * Limit max length of auto generated index names Auto generated index names are now limited to 62 bytes, which fits within diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index ea418c40c9a..62993b68247 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -731,6 +731,8 @@ module ActiveRecord "#{name}_id" elsif options[:as] "#{options[:as]}_id" + elsif options[:inverse_of] + inverse_of.foreign_key else active_record.model_name.to_s.foreign_key end diff --git a/activerecord/test/models/book.rb b/activerecord/test/models/book.rb index d775392471c..edcb28e925c 100644 --- a/activerecord/test/models/book.rb +++ b/activerecord/test/models/book.rb @@ -4,7 +4,7 @@ class Book < ActiveRecord::Base belongs_to :author belongs_to :format_record, polymorphic: true - has_many :citations, foreign_key: "book1_id", inverse_of: :book + has_many :citations, inverse_of: :book has_many :references, -> { distinct }, through: :citations, source: :reference_of has_many :subscriptions diff --git a/activerecord/test/models/comment.rb b/activerecord/test/models/comment.rb index 36e6d29bc37..9ab9e80b265 100644 --- a/activerecord/test/models/comment.rb +++ b/activerecord/test/models/comment.rb @@ -23,7 +23,7 @@ class Comment < ActiveRecord::Base belongs_to :first_post, foreign_key: :post_id belongs_to :special_post_with_default_scope, foreign_key: :post_id - has_many :children, class_name: "Comment", foreign_key: :parent_id, inverse_of: :parent + has_many :children, class_name: "Comment", inverse_of: :parent belongs_to :parent, class_name: "Comment", counter_cache: :children_count, inverse_of: :children alias_attribute :entry, :post diff --git a/activerecord/test/models/company.rb b/activerecord/test/models/company.rb index ca43a61aa8b..f497b9b446a 100644 --- a/activerecord/test/models/company.rb +++ b/activerecord/test/models/company.rb @@ -58,7 +58,7 @@ class Firm < Company has_many :unsorted_clients, class_name: "Client" has_many :unsorted_clients_with_symbol, class_name: :Client has_many :clients_sorted_desc, -> { order "id DESC" }, class_name: "Client" - has_many :clients_of_firm, -> { order "id" }, foreign_key: "client_of", class_name: "Client", inverse_of: :firm + has_many :clients_of_firm, -> { order "id" }, class_name: "Client", inverse_of: :firm has_many :clients_ordered_by_name, -> { order "name" }, class_name: "Client" has_many :unvalidated_clients_of_firm, foreign_key: "client_of", class_name: "Client", validate: false has_many :dependent_clients_of_firm, -> { order "id" }, foreign_key: "client_of", class_name: "Client", dependent: :destroy diff --git a/activerecord/test/models/human.rb b/activerecord/test/models/human.rb index e32a4902d17..fa1a04d2aa3 100644 --- a/activerecord/test/models/human.rb +++ b/activerecord/test/models/human.rb @@ -4,7 +4,7 @@ class Human < ActiveRecord::Base self.table_name = "humans" has_one :face, inverse_of: :human - has_one :autosave_face, class_name: "Face", autosave: true, foreign_key: :human_id, inverse_of: :autosave_human + has_one :autosave_face, class_name: "Face", autosave: true, inverse_of: :autosave_human has_one :polymorphic_face, class_name: "Face", as: :polymorphic_human, inverse_of: :polymorphic_human has_one :polymorphic_face_without_inverse, class_name: "Face", as: :poly_human_without_inverse has_many :interests, inverse_of: :human diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index f5bcb47610f..10d3697502e 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -98,7 +98,7 @@ end class FamousPirate < ActiveRecord::Base self.table_name = "pirates" - has_many :famous_ships, inverse_of: :famous_pirate, foreign_key: :pirate_id + has_many :famous_ships, inverse_of: :famous_pirate validates_presence_of :catchphrase, on: :conference end diff --git a/activerecord/test/models/ship.rb b/activerecord/test/models/ship.rb index 773892edadf..eb08d40fd7d 100644 --- a/activerecord/test/models/ship.rb +++ b/activerecord/test/models/ship.rb @@ -24,7 +24,7 @@ end class ShipWithoutNestedAttributes < ActiveRecord::Base self.table_name = "ships" - has_many :prisoners, inverse_of: :ship, foreign_key: :ship_id + has_many :prisoners, inverse_of: :ship has_many :parts, class_name: "ShipPart", foreign_key: :ship_id validates :name, presence: true, if: -> { true } diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb index fbaee1dd5f1..f4f58434ddb 100644 --- a/activerecord/test/models/topic.rb +++ b/activerecord/test/models/topic.rb @@ -46,7 +46,7 @@ class Topic < ActiveRecord::Base end end - has_many :replies, dependent: :destroy, foreign_key: "parent_id", autosave: true, inverse_of: :topic + has_many :replies, dependent: :destroy, autosave: true, inverse_of: :topic has_many :approved_replies, -> { approved }, class_name: "Reply", foreign_key: "parent_id", counter_cache: "replies_count" has_many :open_replies, -> { open }, class_name: "Reply", foreign_key: "parent_id" diff --git a/activerecord/test/models/zine.rb b/activerecord/test/models/zine.rb index fb4519e289b..6f361665efc 100644 --- a/activerecord/test/models/zine.rb +++ b/activerecord/test/models/zine.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Zine < ActiveRecord::Base - has_many :interests, inverse_of: :zine, foreign_key: "zine_id" + has_many :interests, inverse_of: :zine end