Permalink
Browse files

create_join_table

  • Loading branch information...
1 parent f22a0e2 commit e798a13a2fdccb64c58bfd057d2761f3de3935e1 @kennyj committed Jan 27, 2012
@@ -1,3 +1,4 @@
+require 'active_support/core_ext/array/extract_options'
require 'active_support/deprecation/reporting'
require 'active_record/schema_migration'
@@ -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
@@ -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 = {})
@@ -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)
@@ -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.