Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose foreign key name ignore pattern in configuration #32299

Merged
merged 4 commits into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions activerecord/lib/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module ActiveRecord
autoload :CounterCache
autoload :DynamicMatchers
autoload :Enum
autoload :ForeignKeys
autoload :InternalMetadata
autoload :Explain
autoload :Inheritance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ def validate?
end
alias validated? validate?

def export_name_on_schema_dump?
name !~ ActiveRecord::SchemaDumper.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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ def foreign_key_name(table_name, options)
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

Expand Down
12 changes: 12 additions & 0 deletions activerecord/lib/active_record/foreign_keys.rb
Original file line number Diff line number Diff line change
@@ -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
8 changes: 7 additions & 1 deletion activerecord/lib/active_record/schema_dumper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ class SchemaDumper #:nodoc:
# Only strings are accepted if ActiveRecord::Base.schema_format == :sql.
cattr_accessor :ignore_tables, default: []

##
# :singleton-method:
# Specify a custom regular expression matching foreign keys which name
# should not be dumped to db/schema.rb.
cattr_accessor :fk_ignore_pattern, default: ActiveRecord::ForeignKeys::DEFAULT_IGNORE_PATTERN

class << self
def dump(connection = ActiveRecord::Base.connection, stream = STDOUT, config = ActiveRecord::Base)
connection.create_schema_dumper(generate_options(config)).dump(stream)
Expand Down Expand Up @@ -210,7 +216,7 @@ def foreign_keys(table, stream)
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

Expand Down
11 changes: 11 additions & 0 deletions activerecord/test/cases/migration/foreign_key_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,17 @@ def test_schema_dumping_with_options
assert_match %r{\s+add_foreign_key "fk_test_has_fk", "fk_test_has_pk", column: "fk_id", primary_key: "pk_id", name: "fk_name"$}, output
end

def test_schema_dumping_with_custom_fk_ignore_pattern
original_pattern = ActiveRecord::SchemaDumper.fk_ignore_pattern
ActiveRecord::SchemaDumper.fk_ignore_pattern = /^ignored_/
@connection.add_foreign_key :astronauts, :rockets, name: :ignored_fk_astronauts_rockets

output = dump_table_schema "astronauts"
assert_match %r{\s+add_foreign_key "astronauts", "rockets"$}, output

ActiveRecord::SchemaDumper.fk_ignore_pattern = original_pattern
end

def test_schema_dumping_on_delete_and_on_update_options
@connection.add_foreign_key :astronauts, :rockets, column: "rocket_id", on_delete: :nullify, on_update: :cascade

Expand Down
8 changes: 7 additions & 1 deletion guides/source/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,16 @@ by adding the following to your `application.rb` file:
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
```

The schema dumper adds one additional configuration option:
The schema dumper adds two additional configuration options:

* `ActiveRecord::SchemaDumper.ignore_tables` accepts an array of tables that should _not_ be included in any generated schema file.

* `ActiveRecord::SchemaDumper.fk_ignore_pattern` allows setting a different regular
expression that will be used to decide whether a foreign key's name should be
dumped to db/schema.rb or not. By default, foreign key names starting with
`fk_rails_` are not exported to the database schema dump.
Defaults to `/^fk_rails_[0-9a-f]{10}$/`.

### Configuring Action Controller

`config.action_controller` includes a number of configuration settings:
Expand Down