Module: SchemaPlus::ForeignKeys::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition

Defined in:
lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb

Overview

Instances of this class are returned by the queries ActiveRecord::Base#foreign_keys and ActiveRecord::Base#reverse_foreign_keys (via AbstractAdapter#foreign_keys and AbstractAdapter#reverse_foreign_keys)

The on_update and on_delete attributes can take on the following values:

:cascade
:restrict
:nullify
:set_default
:no_action

The deferrable attribute can take on the following values:

true
:initially_deferred

Constant Summary collapse

ACTIONS =
{ :cascade => "CASCADE", :restrict => "RESTRICT", :nullify => "SET NULL", :set_default => "SET DEFAULT", :no_action => "NO ACTION" }.freeze
ACTION_LOOKUP =
ACTIONS.invert.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_name(from_table, column) ⇒ Object



112
113
114
115
116
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 112

def self.default_name(from_table, column)
  name = "fk_#{fixup_schema_name(from_table)}_#{Array.wrap(column).join('_and_')}"
  name = name.slice(0, 27) + "_" + OpenSSL::Digest::MD5.new.hexdigest(name) if name.length > 60
  name
end

.fixup_schema_name(table_name) ⇒ Object



118
119
120
121
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 118

def self.fixup_schema_name(table_name)
  # replace . with _
  table_name.to_s.gsub(/[.]/, '_')
end

Instance Method Details

#column_namesObject



21
22
23
24
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 21

def column_names
  ActiveSupport::Deprecation.warn "ForeignKeyDefinition#column_names is deprecated, use Array.wrap(column)"
  Array.wrap(column)
end

#deferrableObject

Truthy if the constraint is deferrable



70
71
72
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 70

def deferrable
  options[:deferrable]
end

#initialize(from_table, to_table, options = {}) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 44

def initialize(from_table, to_table, options={})
  [:on_update, :on_delete].each do |key|
    if options[key] == :set_null
      ActiveSupport::Deprecation.warn ":set_null value for #{key} is deprecated.  use :nullify instead"
      options[key] = :nullify
    end
  end

  super from_table, to_table, options

  if column.is_a?(Array) and column.length == 1
    options[:column] = column[0]
  end
  if primary_key.is_a?(Array) and primary_key.length == 1
    options[:primary_key] = primary_key[0]
  end

  ACTIONS.has_key?(on_update) or raise(ArgumentError, "invalid :on_update action: #{on_update.inspect}") if on_update
  ACTIONS.has_key?(on_delete) or raise(ArgumentError, "invalid :on_delete action: #{on_delete.inspect}") if on_delete
  if ::ActiveRecord::Base.connection.adapter_name =~ /^mysql/i
    raise(NotImplementedError, "MySQL does not support ON UPDATE SET DEFAULT") if on_update == :set_default
    raise(NotImplementedError, "MySQL does not support ON DELETE SET DEFAULT") if on_delete == :set_default
  end
end

#match(test) ⇒ Object



123
124
125
126
127
128
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 123

def match(test)
  return false unless from_table == test.from_table
  [:to_table, :column].reject{ |attr| test.send(attr).blank? }.all? { |attr|
    test.send(attr).to_s == self.send(attr).to_s
  }
end

#options_for_dumpObject



80
81
82
83
84
85
86
87
88
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 80

def options_for_dump
  opts = {}
  opts[:primary_key] = self.primary_key if custom_primary_key?
  opts[:name] = name if name
  opts[:on_update] = on_update if on_update
  opts[:on_delete] = on_delete if on_delete
  opts[:deferrable] = deferrable if deferrable
  opts
end

#quoted_column_namesObject



100
101
102
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 100

def quoted_column_names
  Array(column).map { |name| ::ActiveRecord::Base.connection.quote_column_name(name) }
end

#quoted_primary_keysObject



104
105
106
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 104

def quoted_primary_keys
  Array(primary_key).map { |name| ::ActiveRecord::Base.connection.quote_column_name(name) }
end

#quoted_to_tableObject



108
109
110
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 108

def quoted_to_table
  ::ActiveRecord::Base.connection.quote_table_name(to_table)
end

#references_column_namesObject



26
27
28
29
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 26

def references_column_names
  ActiveSupport::Deprecation.warn "ForeignKeyDefinition#references_column_names is deprecated, use Array.wrap(primary_key)"
  Array.wrap(primary_key)
end

#references_table_nameObject



31
32
33
34
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 31

def references_table_name
  ActiveSupport::Deprecation.warn "ForeignKeyDefinition#references_table_name is deprecated, use #to_table"
  to_table
end

#table_nameObject



36
37
38
39
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 36

def table_name
  ActiveSupport::Deprecation.warn "ForeignKeyDefinition#table_name is deprecated, use #from_table"
  from_table
end

#to_dumpObject

Dumps a definition of foreign key.



75
76
77
78
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 75

def to_dump
  opts = {column: self.column}.merge options_for_dump
  dump = "add_foreign_key #{from_table.inspect}, #{to_table.inspect}, #{opts.to_s.sub(/^{(.*)}$/, '\1')}"
end

#to_sqlObject



90
91
92
93
94
95
96
97
98
# File 'lib/schema_plus/foreign_keys/active_record/connection_adapters/foreign_key_definition.rb', line 90

def to_sql
  sql = name ? "CONSTRAINT #{name} " : ""
  sql << "FOREIGN KEY (#{quoted_column_names.join(", ")}) REFERENCES #{quoted_to_table} (#{quoted_primary_keys.join(", ")})"
  sql << " ON UPDATE #{ACTIONS[on_update]}" if on_update
  sql << " ON DELETE #{ACTIONS[on_delete]}" if on_delete
  sql << " DEFERRABLE" if deferrable
  sql << " INITIALLY DEFERRED" if deferrable == :initially_deferred
  sql
end