Add join table migration generator
For instance, running rails g migration CreateMediaJoinTable artists musics:uniq will create a migration with create_join_table :artists, :musics do |t| # t.index [:artist_id, :music_id] t.index [:music_id, :artist_id], unique: true end
This commit is contained in:
parent
d481170251
commit
211d88b71b
@ -206,9 +206,12 @@ def create_join_table(table_1, table_2, options = {})
|
||||
column_options = options.delete(:column_options) || {}
|
||||
column_options.reverse_merge!({:null => false})
|
||||
|
||||
t1_column, t2_column = [table_1, table_2].map{ |t| "#{t.to_s.singularize}_id" }
|
||||
|
||||
create_table(join_table_name, options.merge!(:id => false)) do |td|
|
||||
td.integer :"#{table_1.to_s.singularize}_id", column_options
|
||||
td.integer :"#{table_2.to_s.singularize}_id", column_options
|
||||
td.integer t1_column, column_options
|
||||
td.integer t2_column, column_options
|
||||
yield td if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4,13 +4,11 @@ module JoinTable #:nodoc:
|
||||
private
|
||||
|
||||
def find_join_table_name(table_1, table_2, options = {})
|
||||
options.delete(:table_name) { join_table_name(table_1, table_2) }
|
||||
options.delete(:table_name) || join_table_name(table_1, table_2)
|
||||
end
|
||||
|
||||
def join_table_name(table_1, table_2)
|
||||
tables_names = [table_1, table_2].map(&:to_s).sort
|
||||
|
||||
tables_names.join("_").to_sym
|
||||
[table_1, table_2].sort.join("_").to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -11,15 +11,28 @@ def create_migration_file
|
||||
end
|
||||
|
||||
protected
|
||||
attr_reader :migration_action
|
||||
attr_reader :migration_action, :join_tables
|
||||
|
||||
def set_local_assigns!
|
||||
if file_name =~ /^(add|remove)_.*_(?:to|from)_(.*)/
|
||||
@migration_action = $1
|
||||
@table_name = $2.pluralize
|
||||
def set_local_assigns!
|
||||
case file_name
|
||||
when /^(add|remove)_.*_(?:to|from)_(.*)/
|
||||
@migration_action = $1
|
||||
@table_name = $2.pluralize
|
||||
when /join_table/
|
||||
if attributes.length == 2
|
||||
@migration_action = 'join'
|
||||
@join_tables = attributes.map(&:name)
|
||||
|
||||
set_index_names
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_index_names
|
||||
attributes.each_with_index do |attr, i|
|
||||
attr.index_name = [attr, attributes[i - 1]].map{ |a| :"#{a.name.singularize}_id"}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -12,6 +12,14 @@ def change
|
||||
<%- end -%>
|
||||
<%- end -%>
|
||||
end
|
||||
<%- elsif migration_action == 'join' -%>
|
||||
def change
|
||||
create_join_table :<%= join_tables.first %>, :<%= join_tables.second %> do |t|
|
||||
<%- attributes.each do |attribute| -%>
|
||||
<%= '# ' unless attribute.has_index? -%>t.index <%= attribute.index_name %><%= attribute.inject_index_options %>
|
||||
<%- end -%>
|
||||
end
|
||||
end
|
||||
<%- else -%>
|
||||
def up
|
||||
<% attributes.each do |attribute| -%>
|
||||
@ -40,4 +48,4 @@ def down
|
||||
<%- end -%>
|
||||
end
|
||||
<%- end -%>
|
||||
end
|
||||
end
|
||||
|
@ -42,22 +42,36 @@ def test_create_join_table_with_the_proper_order
|
||||
end
|
||||
|
||||
def test_create_join_table_with_the_table_name
|
||||
connection.create_join_table :artists, :musics, :table_name => :catalog
|
||||
connection.create_join_table :artists, :musics, table_name: :catalog
|
||||
|
||||
assert_equal %w(artist_id music_id), connection.columns(:catalog).map(&:name).sort
|
||||
end
|
||||
|
||||
def test_create_join_table_with_the_table_name_as_string
|
||||
connection.create_join_table :artists, :musics, :table_name => 'catalog'
|
||||
connection.create_join_table :artists, :musics, table_name: 'catalog'
|
||||
|
||||
assert_equal %w(artist_id music_id), connection.columns(:catalog).map(&:name).sort
|
||||
end
|
||||
|
||||
def test_create_join_table_with_column_options
|
||||
connection.create_join_table :artists, :musics, :column_options => {:null => true}
|
||||
connection.create_join_table :artists, :musics, column_options: {null: true}
|
||||
|
||||
assert_equal [true, true], connection.columns(:artists_musics).map(&:null)
|
||||
end
|
||||
|
||||
def test_create_join_table_without_indexes
|
||||
connection.create_join_table :artists, :musics
|
||||
|
||||
assert connection.indexes(:artists_musics).blank?
|
||||
end
|
||||
|
||||
def test_create_join_table_with_index
|
||||
connection.create_join_table :artists, :musics do |t|
|
||||
t.index [:artist_id, :music_id]
|
||||
end
|
||||
|
||||
assert_equal [%w(artist_id music_id)], connection.indexes(:artists_musics).map(&:columns)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -8,6 +8,7 @@ class GeneratedAttribute
|
||||
|
||||
attr_accessor :name, :type
|
||||
attr_reader :attr_options
|
||||
attr_writer :index_name
|
||||
|
||||
class << self
|
||||
def parse(column_definition)
|
||||
@ -94,7 +95,7 @@ def human_name
|
||||
end
|
||||
|
||||
def index_name
|
||||
if reference?
|
||||
@index_name ||= if reference?
|
||||
polymorphic? ? %w(id type).map { |t| "#{name}_#{t}" } : "#{name}_id"
|
||||
else
|
||||
name
|
||||
|
@ -167,6 +167,19 @@ def test_add_migration_with_references_options
|
||||
end
|
||||
end
|
||||
|
||||
def test_create_join_table_migration
|
||||
migration = "add_media_join_table"
|
||||
run_generator [migration, "artists", "musics:uniq"]
|
||||
|
||||
assert_migration "db/migrate/#{migration}.rb" do |content|
|
||||
assert_method :change, content do |up|
|
||||
assert_match(/create_join_table :artists, :musics/, up)
|
||||
assert_match(/# t.index \[:artist_id, :music_id\]/, up)
|
||||
assert_match(/ t.index \[:music_id, :artist_id\], unique: true/, up)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove
|
||||
migration = "create_books"
|
||||
run_generator [migration, "title:string", "content:text"]
|
||||
|
Loading…
Reference in New Issue
Block a user