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

Inherits:
Object
  • 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

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

Instance Method Summary collapse

Constructor Details

#initialize(name, table_name, column_names, references_table_name, references_column_names, on_update = nil, on_delete = nil, deferrable = nil) ⇒ ForeignKeyDefinition

Returns a new instance of ForeignKeyDefinition.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 45

def initialize(name, table_name, column_names, references_table_name, references_column_names, on_update = nil, on_delete = nil, deferrable = nil)
  @name = name
  @table_name = unquote(table_name)
  @column_names = unquote(column_names)
  @references_table_name = unquote(references_table_name)
  @references_column_names = unquote(references_column_names)
  @on_update = on_update
  @on_delete = on_delete
  @deferrable = deferrable

  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).



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

def column_names
  @column_names
end

#deferrableObject (readonly)

True if the constraint is deferrable



39
40
41
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 39

def deferrable
  @deferrable
end

#nameObject (readonly)

The name of the foreign key constraint



15
16
17
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 15

def name
  @name
end

#on_deleteObject (readonly)

The ON_UPDATE behavior for the constraint. See above for the possible values.



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

def on_delete
  @on_delete
end

#on_updateObject (readonly)

The ON_UPDATE behavior for the constraint. See above for the possible values.



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

def on_update
  @on_update
end

#references_column_namesObject (readonly)

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



28
29
30
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 28

def references_column_names
  @references_column_names
end

#references_table_nameObject (readonly)

The foreign table that is referenced by the constraint



24
25
26
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 24

def references_table_name
  @references_table_name
end

#table_nameObject (readonly)

The name of the table the constraint is defined on



18
19
20
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 18

def table_name
  @table_name
end

Instance Method Details

#__unquote(value) ⇒ Object



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

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

#quoted_column_namesObject



89
90
91
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 89

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

#quoted_references_column_namesObject



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

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

#quoted_references_table_nameObject



97
98
99
# File 'lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb', line 97

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

#to_dumpObject

Dumps a definition of foreign key. Must be invoked inside create_table block.

It was introduced to satisfy sqlite which requires foreign key definitions to be declared when creating a table. That approach is fine for MySQL and PostgreSQL too.



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

def to_dump
  dump = "  t.foreign_key"
  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}" if on_update
  dump << ", :on_delete => :#{on_delete}" if on_delete
  dump << ", :deferrable => #{deferrable}" if deferrable
  dump << ", :name => #{name.inspect}" if name
  dump
end

#to_sqlObject



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

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
end

#unquote(names) ⇒ Object



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

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