Module: PgSaurus::ConnectionAdapters::PostgreSQLAdapter::ForeignKeyMethods

Included in:
PgSaurus::ConnectionAdapters::PostgreSQLAdapter
Defined in:
lib/pg_saurus/connection_adapters/postgresql_adapter/foreign_key_methods.rb

Overview

Provides methods to extend ActiveRecord::ConnectionAdapters::PostgreSQLAdapter to support foreign keys feature.

Instance Method Summary collapse

Instance Method Details

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

See activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb Creates index on the FK column by default. Pass in the option :exclude_index => true to disable this.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/foreign_key_methods.rb', line 27

def add_foreign_key(from_table, to_table, options = {})
  exclude_index = (options.has_key?(:exclude_index) ? options.delete(:exclude_index) : false)
  column        = options[:column] || foreign_key_column_for(to_table)

  if index_exists?(from_table, column) && !exclude_index
    raise PgSaurus::IndexExistsError,
          "The index, #{index_name(from_table, column)}, already exists." \
      "  Use :exclude_index => true when adding the foreign key."
  end

  super from_table, to_table, options

  unless exclude_index
    add_index from_table, column
  end
end

#drop_table(*args) ⇒ Object

Drop table and optionally disable triggers. Changes adapted from github.com/matthuhiggins/foreigner/blob/e72ab9c454c156056d3f037d55e3359cd972af32/lib/foreigner/connection_adapters/sql2003.rb NOTE: Disabling referential integrity requires superuser access in postgres.

Default AR behavior is just to drop_table.

Options:

  • :force - force disabling of referential integrity

Note: I don’t know a good way to test this -mike 20120420



15
16
17
18
19
20
21
22
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/foreign_key_methods.rb', line 15

def drop_table(*args)
  options = args.clone.extract_options!
  if options[:force]
    disable_referential_integrity { super }
  else
    super
  end
end

#foreign_key_column_for(table_name) ⇒ Object

See: activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb



55
56
57
58
59
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/foreign_key_methods.rb', line 55

def foreign_key_column_for(table_name)
  table = table_name.to_s.split('.').last

  super table
end

#foreign_keys(table_name) ⇒ Object

see activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/foreign_key_methods.rb', line 62

def foreign_keys(table_name)
  namespace  = table_name.to_s.split('.').first
  table_name = table_name.to_s.split('.').last

  namespace  = if namespace == table_name
                 "ANY (current_schemas(false))"
               else
                 quote(namespace)
               end

  sql = "        SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete, t3.nspname AS from_schema\n        FROM pg_constraint c\n        JOIN pg_class t1 ON c.conrelid = t1.oid\n        JOIN pg_class t2 ON c.confrelid = t2.oid\n        JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid\n        JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid\n        JOIN pg_namespace t3 ON c.connamespace = t3.oid\n        WHERE c.contype = 'f'\n          AND t1.relname = \#{quote(table_name)}\n          AND t3.nspname = \#{namespace}\n        ORDER BY c.conname\n  SQL\n\n  fk_info = select_all(sql)\n\n  fk_info.map do |row|\n    options = {\n      column:      row['column'],\n      name:        row['name'],\n      primary_key: row['primary_key'],\n      from_schema: row['from_schema']\n    }\n\n    options[:on_delete] = extract_foreign_key_action(row['on_delete'])\n    options[:on_update] = extract_foreign_key_action(row['on_update'])\n\n    ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, row['to_table'], options)\n  end\nend\n".strip_heredoc

#remove_foreign_key(from_table, options_or_to_table = {}) ⇒ Object

See activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb



45
46
47
48
49
50
51
52
# File 'lib/pg_saurus/connection_adapters/postgresql_adapter/foreign_key_methods.rb', line 45

def remove_foreign_key(from_table, options_or_to_table = {})
  if options_or_to_table.is_a?(Hash) && options_or_to_table[:remove_index]
    column = options_or_to_table[:column]
    remove_index from_table, column
  end

  super(from_table, options_or_to_table)
end