aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-12-23 09:14:23 -0700
committerSean Griffin <sean@thoughtbot.com>2014-12-23 09:20:54 -0700
commitd26704a15f88d384dd282425daa832affdb5f8c1 (patch)
treed2dde416ae8999199c37f415a510b5b114a47dd0 /activerecord/lib/active_record/connection_adapters/abstract
parentaffae7d904e1dd91c89f8126358a2d2fbbe49eeb (diff)
downloadrails-d26704a15f88d384dd282425daa832affdb5f8c1.tar.gz
rails-d26704a15f88d384dd282425daa832affdb5f8c1.tar.bz2
rails-d26704a15f88d384dd282425daa832affdb5f8c1.zip
Refactor a common class to reduce the duplication for `references`
The code for `TableDefinition#references` and `SchemaStatements#add_reference` were almost identical both structurally, and in terms of domain knowledge. This removes that duplication into a common class, using the `Table` API as the expected interface of its collaborator.
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb113
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb32
2 files changed, 86 insertions, 59 deletions
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 11c2e8f773..8defc3986f 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -68,6 +68,84 @@ module ActiveRecord
end
end
+ class ReferenceDefinition # :nodoc:
+ def initialize(
+ name,
+ polymorphic: false,
+ index: false,
+ foreign_key: false,
+ type: :integer,
+ **options
+ )
+ @name = name
+ @polymorphic = polymorphic
+ @index = index
+ @foreign_key = foreign_key
+ @type = type
+ @options = options
+
+ if polymorphic && foreign_key
+ raise ArgumentError, "Cannot add a foreign key to a polymorphic relation"
+ end
+ end
+
+ def add_to(table)
+ columns.each do |column_options|
+ table.column(*column_options)
+ end
+
+ if index
+ table.index(column_names, index_options)
+ end
+
+ if foreign_key
+ table.foreign_key(foreign_table_name, foreign_key_options)
+ end
+ end
+
+ protected
+
+ attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options
+
+ private
+
+ def as_options(value, default = {})
+ if value.is_a?(Hash)
+ value
+ else
+ default
+ end
+ end
+
+ def polymorphic_options
+ as_options(polymorphic, options)
+ end
+
+ def index_options
+ as_options(index)
+ end
+
+ def foreign_key_options
+ as_options(foreign_key)
+ end
+
+ def columns
+ result = [["#{name}_id", type, options]]
+ if polymorphic
+ result.unshift(["#{name}_type", :string, polymorphic_options])
+ end
+ result
+ end
+
+ def column_names
+ columns.map(&:first)
+ end
+
+ def foreign_table_name
+ name.to_s.pluralize
+ end
+ end
+
# Represents the schema of an SQL table in an abstract way. This class
# provides methods for manipulating the schema representation.
#
@@ -314,36 +392,9 @@ module ActiveRecord
# t.belongs_to(:supplier, polymorphic: true)
#
# See SchemaStatements#add_reference
- def references(
- *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
-
+ def references(*args, **options)
args.each do |col|
- column("#{col}_id", type, options)
-
- if polymorphic
- column("#{col}_type", :string, polymorphic_options)
- end
-
- 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
+ ReferenceDefinition.new(col, **options).add_to(self)
end
end
alias :belongs_to :references
@@ -597,6 +648,10 @@ module ActiveRecord
end
end
+ def foreign_key(*args) # :nodoc:
+ @base.add_foreign_key(name, *args)
+ end
+
private
def native
@base.native_database_types
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 a19bcc86c2..6e42089801 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -645,36 +645,8 @@ module ActiveRecord
#
# add_reference(:products, :supplier, foreign_key: true)
#
- def add_reference(
- table_name,
- ref_name,
- 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 to a polymorphic relation"
- end
-
- add_column(table_name, "#{ref_name}_id", type, options)
-
- if polymorphic
- add_column(table_name, "#{ref_name}_type", :string, polymorphic_options)
- end
-
- if index
- add_index(table_name, polymorphic ? %w[type id].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options)
- end
-
- if foreign_key
- add_foreign_key(table_name, ref_name.to_s.pluralize, foreign_key_options)
- end
+ def add_reference(table_name, *args)
+ ReferenceDefinition.new(*args).add_to(update_table_definition(table_name, self))
end
alias :add_belongs_to :add_reference