Skip to content

Commit

Permalink
Rails 4.0 supports adding indexes during create_table. We shall do th…
Browse files Browse the repository at this point in the history
…e same for foreign_keys.

spread out some code. Make table_definitions test work

test file

fix up create_table override
  • Loading branch information
matthuhiggins committed Jan 14, 2013
1 parent 54bd87f commit 0e5a9ed
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 54 deletions.
2 changes: 2 additions & 0 deletions lib/foreigner.rb
Expand Up @@ -13,6 +13,8 @@ module ConnectionAdapters
autoload :ForeignKeyDefinition autoload :ForeignKeyDefinition
autoload :SchemaDefinitions autoload :SchemaDefinitions
autoload :SchemaStatements autoload :SchemaStatements
autoload :Table
autoload :TableDefinition
end end
end end


Expand Down
56 changes: 2 additions & 54 deletions lib/foreigner/connection_adapters/abstract/schema_definitions.rb
Expand Up @@ -5,62 +5,10 @@ def self.included(base)
base::Table.class_eval do base::Table.class_eval do
include Foreigner::ConnectionAdapters::Table include Foreigner::ConnectionAdapters::Table
end end
end
end

module Table
extend ActiveSupport::Concern

included do
alias_method_chain :references, :foreign_keys
end


# Adds a new foreign key to the table. +to_table+ can be a single Symbol, or base::TableDefinition.class_eval do
# an Array of Symbols. See SchemaStatements#add_foreign_key include Foreigner::ConnectionAdapters::TableDefinition
#
# ===== Examples
# ====== Creating a simple foreign key
# t.foreign_key(:people)
# ====== Defining the column
# t.foreign_key(:people, column: :sender_id)
# ====== Creating a named foreign key
# t.foreign_key(:people, column: :sender_id, name: 'sender_foreign_key')
# ====== Defining the column of the +to_table+.
# t.foreign_key(:people, column: :sender_id, primary_key: :person_id)
def foreign_key(to_table, options = {})
@base.add_foreign_key(@table_name, to_table, options)
end

# Remove the given foreign key from the table.
#
# ===== Examples
# ====== Remove the suppliers_company_id_fk in the suppliers table.
# change_table :suppliers do |t|
# t.remove_foreign_key :companies
# end
# ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
# change_table :accounts do |t|
# t.remove_foreign_key column: :branch_id
# end
# ====== Remove the foreign key named party_foreign_key in the accounts table.
# change_table :accounts do |t|
# t.remove_index name: :party_foreign_key
# end
def remove_foreign_key(options)
@base.remove_foreign_key(@table_name, options)
end

# Deprecated
def references_with_foreign_keys(*args)
options = args.extract_options!

if fk_options = options.delete(:foreign_key)
p ActiveSupport::Deprecation.send(:deprecation_message, caller,
":foreign_key in t.references is deprecated. " \
"Use t.foreign_key instead")
end end

references_without_foreign_keys(*(args.dup << options))
end end
end end
end end
Expand Down
Expand Up @@ -9,6 +9,15 @@ def self.included(base)
end end


module AbstractAdapter module AbstractAdapter
def create_table(table_name, *args, &block)
definition = nil
super do |td|
definition = td # This is my trick to get the definition
block.call(td)
end
definition.foreign_keys.each { |c,o| add_foreign_key table_name, c, o }
end

def supports_foreign_keys? def supports_foreign_keys?
false false
end end
Expand Down
59 changes: 59 additions & 0 deletions lib/foreigner/connection_adapters/abstract/table.rb
@@ -0,0 +1,59 @@
module Foreigner
module ConnectionAdapters
module Table
extend ActiveSupport::Concern

included do
alias_method_chain :references, :foreign_keys
end

# Adds a new foreign key to the table. +to_table+ can be a single Symbol, or
# an Array of Symbols. See SchemaStatements#add_foreign_key
#
# ===== Examples
# ====== Creating a simple foreign key
# t.foreign_key(:people)
# ====== Defining the column
# t.foreign_key(:people, column: :sender_id)
# ====== Creating a named foreign key
# t.foreign_key(:people, column: :sender_id, name: 'sender_foreign_key')
# ====== Defining the column of the +to_table+.
# t.foreign_key(:people, column: :sender_id, primary_key: :person_id)
def foreign_key(to_table, options = {})
@base.add_foreign_key(@table_name, to_table, options)
end

# Remove the given foreign key from the table.
#
# ===== Examples
# ====== Remove the suppliers_company_id_fk in the suppliers table.
# change_table :suppliers do |t|
# t.remove_foreign_key :companies
# end
# ====== Remove the foreign key named accounts_branch_id_fk in the accounts table.
# change_table :accounts do |t|
# t.remove_foreign_key column: :branch_id
# end
# ====== Remove the foreign key named party_foreign_key in the accounts table.
# change_table :accounts do |t|
# t.remove_index name: :party_foreign_key
# end
def remove_foreign_key(options)
@base.remove_foreign_key(@table_name, options)
end

# Deprecated
def references_with_foreign_keys(*args)
options = args.extract_options!

if fk_options = options.delete(:foreign_key)
p ActiveSupport::Deprecation.send(:deprecation_message, caller,
":foreign_key in t.references is deprecated. " \
"Use t.foreign_key instead")
end

references_without_foreign_keys(*(args.dup << options))
end
end
end
end
13 changes: 13 additions & 0 deletions lib/foreigner/connection_adapters/abstract/table_definition.rb
@@ -0,0 +1,13 @@
module Foreigner
module ConnectionAdapters
module TableDefinition
def foreign_key(to_table, options = {})
foreign_keys[to_table] = options
end

def foreign_keys
@foreign_keys ||= {}
end
end
end
end
@@ -0,0 +1,5 @@
require 'helper'

class Foreigner::ConnectionAdapters::SchemaStatementsTest < ActiveSupport::TestCase

end
@@ -0,0 +1,13 @@
require 'helper'

class Foreigner::ConnectionAdapters::TableDefinitionsTest < ActiveSupport::TestCase
class TestDefinition
include Foreigner::ConnectionAdapters::TableDefinition
end

test "foreign_key" do
definition = TestDefinition.new
definition.foreign_key :poops, and: :one;
assert_equal definition.foreign_keys[:poops], and: :one
end
end

0 comments on commit 0e5a9ed

Please sign in to comment.