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 = options.delete(:column_options) || {}
|
||||||
column_options.reverse_merge!({:null => false})
|
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|
|
create_table(join_table_name, options.merge!(:id => false)) do |td|
|
||||||
td.integer :"#{table_1.to_s.singularize}_id", column_options
|
td.integer t1_column, column_options
|
||||||
td.integer :"#{table_2.to_s.singularize}_id", column_options
|
td.integer t2_column, column_options
|
||||||
|
yield td if block_given?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,13 +4,11 @@ module JoinTable #:nodoc:
|
|||||||
private
|
private
|
||||||
|
|
||||||
def find_join_table_name(table_1, table_2, options = {})
|
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
|
end
|
||||||
|
|
||||||
def join_table_name(table_1, table_2)
|
def join_table_name(table_1, table_2)
|
||||||
tables_names = [table_1, table_2].map(&:to_s).sort
|
[table_1, table_2].sort.join("_").to_sym
|
||||||
|
|
||||||
tables_names.join("_").to_sym
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,15 +11,28 @@ def create_migration_file
|
|||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
attr_reader :migration_action
|
attr_reader :migration_action, :join_tables
|
||||||
|
|
||||||
def set_local_assigns!
|
def set_local_assigns!
|
||||||
if file_name =~ /^(add|remove)_.*_(?:to|from)_(.*)/
|
case file_name
|
||||||
@migration_action = $1
|
when /^(add|remove)_.*_(?:to|from)_(.*)/
|
||||||
@table_name = $2.pluralize
|
@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
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,6 +12,14 @@ def change
|
|||||||
<%- end -%>
|
<%- end -%>
|
||||||
<%- end -%>
|
<%- 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 -%>
|
<%- else -%>
|
||||||
def up
|
def up
|
||||||
<% attributes.each do |attribute| -%>
|
<% attributes.each do |attribute| -%>
|
||||||
@ -40,4 +48,4 @@ def down
|
|||||||
<%- end -%>
|
<%- end -%>
|
||||||
end
|
end
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
end
|
end
|
||||||
|
@ -42,22 +42,36 @@ def test_create_join_table_with_the_proper_order
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_create_join_table_with_the_table_name
|
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
|
assert_equal %w(artist_id music_id), connection.columns(:catalog).map(&:name).sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create_join_table_with_the_table_name_as_string
|
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
|
assert_equal %w(artist_id music_id), connection.columns(:catalog).map(&:name).sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_create_join_table_with_column_options
|
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)
|
assert_equal [true, true], connection.columns(:artists_musics).map(&:null)
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -8,6 +8,7 @@ class GeneratedAttribute
|
|||||||
|
|
||||||
attr_accessor :name, :type
|
attr_accessor :name, :type
|
||||||
attr_reader :attr_options
|
attr_reader :attr_options
|
||||||
|
attr_writer :index_name
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def parse(column_definition)
|
def parse(column_definition)
|
||||||
@ -94,7 +95,7 @@ def human_name
|
|||||||
end
|
end
|
||||||
|
|
||||||
def index_name
|
def index_name
|
||||||
if reference?
|
@index_name ||= if reference?
|
||||||
polymorphic? ? %w(id type).map { |t| "#{name}_#{t}" } : "#{name}_id"
|
polymorphic? ? %w(id type).map { |t| "#{name}_#{t}" } : "#{name}_id"
|
||||||
else
|
else
|
||||||
name
|
name
|
||||||
|
@ -167,6 +167,19 @@ def test_add_migration_with_references_options
|
|||||||
end
|
end
|
||||||
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
|
def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove
|
||||||
migration = "create_books"
|
migration = "create_books"
|
||||||
run_generator [migration, "title:string", "content:text"]
|
run_generator [migration, "title:string", "content:text"]
|
||||||
|
Loading…
Reference in New Issue
Block a user