From 99a6f9e60ea55924b44f894a16f8de0162cf2702 Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Mon, 22 Dec 2014 13:09:49 -0700 Subject: Add a `foreign_key` option to `references` while creating the table Rather than having to do: create_table :posts do |t| t.references :user end add_foreign_key :posts, :users You can instead do: create_table :posts do |t| t.references :user, foreign_key: true end Similar to the `index` option, you can also pass a hash. This will be passed as the options to `add_foreign_key`. e.g.: create_table :posts do |t| t.references :user, foreign_key: { primary_key: :other_id } end is equivalent to create_table :posts do |t| t.references :user end add_foreign_key :posts, :users, primary_key: :other_id --- .../abstract/schema_definitions.rb | 27 ++++++++++++++++++---- .../abstract/schema_statements.rb | 12 +++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters/abstract') diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 33419680fb..639b87d211 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -94,11 +94,12 @@ module ActiveRecord # An array of ColumnDefinition objects, representing the column changes # that have been defined. attr_accessor :indexes - attr_reader :name, :temporary, :options, :as + attr_reader :name, :temporary, :options, :as, :foreign_keys def initialize(types, name, temporary, options, as = nil) @columns_hash = {} @indexes = {} + @foreign_keys = {} @native = types @temporary = temporary @options = options @@ -286,6 +287,10 @@ module ActiveRecord indexes[column_name] = options end + def foreign_key(table_name, options = {}) # :nodoc: + foreign_keys[table_name] = options + end + # Appends :datetime columns :created_at and # :updated_at to the table. See SchemaStatements#add_timestamps # @@ -297,9 +302,12 @@ module ActiveRecord column(:updated_at, :datetime, options) end - # Adds a reference. Optionally adds a +type+ column, if :polymorphic option is provided. - # references and belongs_to are acceptable. The reference column will be an +integer+ - # by default, the :type option can be used to specify a different type. + # Adds a reference. Optionally adds a +type+ column, if + # :polymorphic option is provided. references and + # belongs_to are acceptable. The reference column will be an + # +integer+ by default, the :type option can be used to specify + # a different type. A foreign key will be created if a +foreign_key+ + # option is passed. # # t.references(:user) # t.references(:user, type: "string") @@ -310,11 +318,18 @@ module ActiveRecord *args, polymorphic: false, index: false, + foreign_key: false, type: :integer, **options ) polymorphic_options = polymorphic.is_a?(Hash) ? polymorphic : options index_options = index.is_a?(Hash) ? index : {} + foreign_key_options = foreign_key.is_a?(Hash) ? foreign_key : {} + + if polymorphic && foreign_key + raise ArgumentError, "Cannot add a foreign key on a polymorphic relation" + end + args.each do |col| column("#{col}_id", type, options) @@ -325,6 +340,10 @@ module ActiveRecord if index self.index(polymorphic ? %w(type id).map { |t| "#{col}_#{t}" } : "#{col}_id", index_options) end + + if foreign_key + self.foreign_key(col.to_s.pluralize, foreign_key_options) + end end end alias :belongs_to :references diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index b340e8334b..b22a304d4c 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -204,7 +204,17 @@ module ActiveRecord end result = execute schema_creation.accept td - td.indexes.each_pair { |c, o| add_index(table_name, c, o) } unless supports_indexes_in_create? + + unless supports_indexes_in_create? + td.indexes.each_pair do |column_name, index_options| + add_index(table_name, column_name, index_options) + end + end + + td.foreign_keys.each_pair do |other_table_name, foreign_key_options| + add_foreign_key(table_name, other_table_name, foreign_key_options) + end + result end -- cgit v1.2.3