Skip to content

Commit

Permalink
create_join_table
Browse files Browse the repository at this point in the history
  • Loading branch information
kennyj committed Jan 27, 2012
1 parent f22a0e2 commit e798a13
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'active_support/core_ext/array/extract_options'
require 'active_support/deprecation/reporting'
require 'active_record/schema_migration'

Expand Down Expand Up @@ -170,6 +171,20 @@ def create_table(table_name, options = {})
execute create_sql
end

# Creates a new join table.
def create_join_table(*table_name_or_options)
table_name, from, to, options = parse_arguments(table_name_or_options)

create_table(table_name, options.merge(:id => false)) do |t|
t.references from, to, :null => false
end

if options.delete(:index)
add_index table_name, "#{from}_id"
add_index table_name, "#{to}_id"
end
end

# A block for changing columns in +table+.
#
# === Example
Expand Down Expand Up @@ -256,6 +271,12 @@ def drop_table(table_name)
execute "DROP TABLE #{quote_table_name(table_name)}"
end

# Drops a join table from the database.
def drop_join_table(*table_name_or_options)
table_name, _ = parse_arguments(table_name_or_options)
drop_table table_name
end

# Adds a new column to the named table.
# See TableDefinition#column for details of the options you can use.
def add_column(table_name, column_name, type, options = {})
Expand Down Expand Up @@ -571,6 +592,23 @@ def columns_for_remove(table_name, *column_names)
column_names.map {|column_name| quote_column_name(column_name) }
end

def extract_references(options)
[options.delete(:tie), options.delete(:to)].sort
end

def join_table_name(from, to)
"#{from.to_s.pluralize}_#{to.to_s.pluralize}"
end

def parse_arguments(table_name_or_options)
options = table_name_or_options.extract_options!

from, to = extract_references(options)
table_name = table_name_or_options.empty? ? join_table_name(from, to) : table_name_or_options.first

[table_name, from, to, options]
end

private
def table_definition
TableDefinition.new(self)
Expand Down
64 changes: 64 additions & 0 deletions activerecord/test/cases/migration/create_join_table_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require "cases/migration/helper"

module ActiveRecord
class Migration
class CreateJoinTableTest < ActiveRecord::TestCase
include ActiveRecord::Migration::TestHelper

self.use_transactional_fixtures = false

def setup
super
end

def test_create_join_table
con = connection

create_join_table :tie => :person, :to => :group

table_name = "groups_people"
assert con.table_exists?(table_name)

columns = con.columns(table_name)
assert !columns.find { |c| c.name == "group_id" }.null
assert !columns.find { |c| c.name == "person_id" }.null

assert !con.index_name_exists?(table_name, "index_groups_people_on_group_id", false)
assert !con.index_name_exists?(table_name, "index_groups_people_on_person_id", false)
ensure
drop_join_table :tie => :person, :to => :group
end

def test_create_join_table_with_index
con = connection

create_join_table :tie => :person, :to => :group, :index => true

table_name = "groups_people"
assert con.index_name_exists?(table_name, "index_groups_people_on_group_id", false)
assert con.index_name_exists?(table_name, "index_groups_people_on_person_id", false)
ensure
drop_join_table :tie => :person, :to => :group
end

def test_create_join_table_with_table_name_and_options
table_name = "habtm"
create_join_table table_name, :tie => :person, :to => :group
assert connection.table_exists?(table_name)
ensure
drop_join_table table_name
end

private

def create_join_table(*args)
connection.create_join_table(*args)
end

def drop_join_table(*args)
connection.drop_join_table(*args)
end

end
end
end

0 comments on commit e798a13

Please sign in to comment.