Class: SchemaPlus::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition

Inherits:
ActiveRecord::ConnectionAdapters::ForeignKeyDefinition
  • Object
show all
Defined in:
lib/schema_plus/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
:set_null
:set_default
:no_action

The deferrable attribute can take on the following values:

true
:initially_deferred

Constant Summary collapse

ACTIONS =

:enddoc:

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(from_table, to_table, options) ⇒ ForeignKeyDefinition

Returns a new instance of ForeignKeyDefinition.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 68

def initialize(from_table, to_table, options) 
  super
  @from_table = unquote(from_table)
  @to_table = unquote(to_table)
  @column_names = unquote(Array.wrap(options.delete(:column_names)))
  @references_column_names = unquote(Array.wrap(options.delete(:references_column_names)))

  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

Instance Attribute Details

#column_namesObject (readonly)

The list of column names that are constrained (as strings).



59
60
61
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 59

def column_names
  @column_names
end

#references_column_namesObject (readonly)

The list of column names (as strings) of the foreign table that are referenced by the constraint



63
64
65
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 63

def references_column_names
  @references_column_names
end

Class Method Details

.auto_index_name(table_name, column_name) ⇒ Object



147
148
149
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 147

def self.auto_index_name(table_name, column_name)
  "fk__#{fixup_schema_name(table_name)}_#{Array.wrap(column_name).join('_and_')}"
end

.default_name(table_name, column_names) ⇒ Object



143
144
145
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 143

def self.default_name(table_name, column_names)
  "fk_#{fixup_schema_name(table_name)}_#{Array.wrap(column_names).join('_and_')}"
end

.fixup_schema_name(table_name) ⇒ Object



151
152
153
154
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 151

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

Instance Method Details

#==(other) ⇒ Object

note equality test ignores :name and options



156
157
158
159
160
161
162
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 156

def ==(other) # note equality test ignores :name and options
  [:table_name,
   :column_names,
   :references_table_name,
   :references_column_names
   ].all? { |attr| self.send(attr) == other.send(attr) }
end

#__unquote(value) ⇒ Object



139
140
141
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 139

def __unquote(value)
  value.to_s.sub(/^["`](.*)["`]$/, '\1')
end

#deferrableObject

True if the constraint is deferrable



92
93
94
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 92

def deferrable
  options[:deferrable]
end

#quoted_column_namesObject



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

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

#quoted_references_column_namesObject



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

def quoted_references_column_names
  Array(references_column_names).collect { |name| ::ActiveRecord::Base.connection.quote_column_name(name) }
end

#quoted_references_table_nameObject



127
128
129
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 127

def quoted_references_table_name
  ::ActiveRecord::Base.connection.quote_table_name(references_table_name)
end

#references_table_nameObject



87
88
89
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 87

def references_table_name
  to_table
end

#table_nameObject



83
84
85
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 83

def table_name
  from_table
end

#to_dump(opts = {}) ⇒ Object

Dumps a definition of foreign key.



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 97

def to_dump(opts={})
  dump = (opts[:inline] ? "  t.foreign_key" : "add_foreign_key #{table_name.inspect},")
  dump << " [#{Array(column_names).collect{ |name| name.inspect }.join(', ')}]"
  dump << ", #{references_table_name.inspect}, [#{Array(references_column_names).collect{ |name| name.inspect }.join(', ')}]"
  dump << ", :on_update => #{on_update.inspect}" if on_update
  dump << ", :on_delete => #{on_delete.inspect}" if on_delete
  dump << ", :deferrable => #{deferrable.inspect}" if deferrable
  dump << ", :name => #{name.inspect}" if name
  dump << "\n"
  dump
end

#to_sqlObject



109
110
111
112
113
114
115
116
117
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 109

def to_sql
  sql = name ? "CONSTRAINT #{name} " : ""
  sql << "FOREIGN KEY (#{quoted_column_names.join(", ")}) REFERENCES #{quoted_references_table_name} (#{quoted_references_column_names.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

#unquote(names) ⇒ Object



131
132
133
134
135
136
137
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 131

def unquote(names)
  if names.is_a?(Array)
    names.collect { |name| __unquote(name) }
  else
    __unquote(names)
  end
end