aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorDavid Stosik <david.stosik+git-noreply@gmail.com>2018-03-19 17:42:23 +0000
committerDavid Stosik <david.stosik+git-noreply@gmail.com>2018-03-19 17:42:23 +0000
commitd3fd4e4ed9bae3775969c5c913b15bbd927e9ad9 (patch)
treee560afb7d4bc1cf4f00a26eec408aee1d299ed0b /activerecord
parentd7b72761043f8d76dd95a7198c2dbba89da13b0b (diff)
downloadrails-d3fd4e4ed9bae3775969c5c913b15bbd927e9ad9.tar.gz
rails-d3fd4e4ed9bae3775969c5c913b15bbd927e9ad9.tar.bz2
rails-d3fd4e4ed9bae3775969c5c913b15bbd927e9ad9.zip
Expose foreign key name ignore pattern in configuration
When dumping the database schema, Rails will dump foreign key names only if those names were not generate by Rails. Currently this is determined by checking if the foreign key name is `fk_rails_` followed by a 10-character hash. At [Cookpad](https://github.com/cookpad), we use [Departure](https://github.com/departurerb/departure) (Percona's pt-online-schema-change runner for ActiveRecord migrations) to run migrations. Often, `pt-osc` will make a copy of a table in order to run a long migration without blocking it. In this copy process, foreign keys are copied too, but [their name is prefixed with an underscore to prevent name collision ](https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html#cmdoption-pt-online-schema-change-alter-foreign-keys-method). In the process described above, we often end up with a development database that contains foreign keys which name starts with `_fk_rails_`. That name does not match the ignore pattern, so next time Rails dumps the database schema (eg. when running `rake db:migrate`), our `db/schema.rb` file ends up containing those unwanted foreign key names. This also produces an unwanted git diff that we'd prefer not to commit. In this PR, I'd like to suggest a way to expose the foreign key name ignore pattern to the Rails configuration, so that individual projects can decide on a different pattern of foreign keys that will not get their names dumped in `schema.rb`.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb2
-rw-r--r--activerecord/lib/active_record/core.rb2
-rw-r--r--activerecord/lib/active_record/foreign_keys.rb12
-rw-r--r--activerecord/lib/active_record/railtie.rb1
-rw-r--r--activerecord/lib/active_record/schema_dumper.rb2
7 files changed, 22 insertions, 2 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb
index d43378c64f..66084e9b1c 100644
--- a/activerecord/lib/active_record.rb
+++ b/activerecord/lib/active_record.rb
@@ -42,6 +42,7 @@ module ActiveRecord
autoload :CounterCache
autoload :DynamicMatchers
autoload :Enum
+ autoload :ForeignKeys
autoload :InternalMetadata
autoload :Explain
autoload :Inheritance
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 584a86da21..b91f591e1a 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -101,6 +101,10 @@ module ActiveRecord
end
alias validated? validate?
+ def export_name_on_schema_dump?
+ name !~ ActiveRecord::Base.fk_ignore_pattern
+ end
+
def defined_for?(to_table_ord = nil, to_table: nil, **options)
if to_table_ord
self.to_table == to_table_ord.to_s
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 e2147b7fcf..ef45fff9d2 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -1324,7 +1324,7 @@ module ActiveRecord
identifier = "#{table_name}_#{options.fetch(:column)}_fk"
hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10)
- "fk_rails_#{hashed_identifier}"
+ "#{ActiveRecord::ForeignKeys::PREFIX}_#{hashed_identifier}"
end
end
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb
index e1a0b2ecf8..cb0be9787f 100644
--- a/activerecord/lib/active_record/core.rb
+++ b/activerecord/lib/active_record/core.rb
@@ -125,6 +125,8 @@ module ActiveRecord
mattr_accessor :belongs_to_required_by_default, instance_accessor: false
+ mattr_accessor :fk_ignore_pattern, instance_accessor: false
+
class_attribute :default_connection_handler, instance_writer: false
def self.connection_handler
diff --git a/activerecord/lib/active_record/foreign_keys.rb b/activerecord/lib/active_record/foreign_keys.rb
new file mode 100644
index 0000000000..87ce3ace20
--- /dev/null
+++ b/activerecord/lib/active_record/foreign_keys.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module ActiveRecord
+ module ForeignKeys
+ # The prefix used by Rails to name unnamed foreign keys.
+ PREFIX = "fk_rails"
+
+ # Default regular expression used by Rails to determine if a foreign key
+ # name was generated.
+ DEFAULT_IGNORE_PATTERN = /^#{PREFIX}_[0-9a-f]{10}$/
+ end
+end
diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb
index 6ab80a654d..7f58780fdf 100644
--- a/activerecord/lib/active_record/railtie.rb
+++ b/activerecord/lib/active_record/railtie.rb
@@ -27,6 +27,7 @@ module ActiveRecord
config.active_record.use_schema_cache_dump = true
config.active_record.maintain_test_schema = true
+ config.active_record.fk_ignore_pattern = ActiveRecord::ForeignKeys::DEFAULT_IGNORE_PATTERN
config.active_record.sqlite3 = ActiveSupport::OrderedOptions.new
config.active_record.sqlite3.represent_boolean_as_integer = nil
diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb
index b8d848b999..72b7460342 100644
--- a/activerecord/lib/active_record/schema_dumper.rb
+++ b/activerecord/lib/active_record/schema_dumper.rb
@@ -210,7 +210,7 @@ HEADER
parts << "primary_key: #{foreign_key.primary_key.inspect}"
end
- if foreign_key.name !~ /^fk_rails_[0-9a-f]{10}$/
+ if foreign_key.export_name_on_schema_dump?
parts << "name: #{foreign_key.name.inspect}"
end