1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Support creating a table migration generator

Sometimes you want to create a table without an associated model and
test, which is also not a join table. With this commit, you can now
do that.

Example:

    rails g migration create_posts title:string
or
    rails g migration CreatePosts title:string

This commit also moves the template the model generator uses for the
migration to the migration templates folder, as it seems a more
sensible place for it now that it is shared code.
This commit is contained in:
Sammy Larbi 2012-12-26 13:02:28 -06:00
parent bb9f8312e7
commit 20e041579f
6 changed files with 57 additions and 7 deletions

View file

@ -1,5 +1,15 @@
## Rails 4.0.0 (unreleased) ##
* Added support for creating a table via Rails migration generator.
For example,
rails g migration create_books title:string content:text
will generate a migration that creates a table called books with
the listed attributes, without creating a model.
*Sammy Larbi*
* Fix bug that raises the wrong exception when the exception handled by PostgreSQL adapter
doesn't respond to `#result`.
Fixes #8617.
@ -362,7 +372,7 @@
deprecated and removed in future versions of Rails.
*Amparo Luna + Guillermo Iguaran*
* `after_commit` and `after_rollback` now validate the `:on` option and raise an `ArgumentError`
if it is not one of `:create`, `:destroy` or `:update`
@ -1549,4 +1559,5 @@
*Aaron Patterson*
Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/activerecord/CHANGELOG.md) for previous changes.

View file

@ -8,13 +8,14 @@ module ActiveRecord
def create_migration_file
set_local_assigns!
validate_file_name!
migration_template "migration.rb", "db/migrate/#{file_name}.rb"
migration_template @migration_template, "db/migrate/#{file_name}.rb"
end
protected
attr_reader :migration_action, :join_tables
def set_local_assigns!
@migration_template = "migration.rb"
case file_name
when /^(add|remove)_.*_(?:to|from)_(.*)/
@migration_action = $1
@ -26,6 +27,9 @@ module ActiveRecord
set_index_names
end
when /^create_(.+)/
@table_name = $1.pluralize
@migration_template = "create_table_migration.rb"
end
end
@ -44,7 +48,10 @@ module ActiveRecord
end
private
def attributes_with_index
attributes.select { |a| !a.reference? && a.has_index? }
end
def validate_file_name!
unless file_name =~ /^[_a-z0-9]+$/
raise IllegalMigrationNameError.new(file_name)

View file

@ -15,7 +15,7 @@ module ActiveRecord
def create_migration_file
return unless options[:migration] && options[:parent].nil?
attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? } if options[:indexes] == false
migration_template "migration.rb", "db/migrate/create_#{table_name}.rb"
migration_template "../../migration/templates/create_table_migration.rb", "db/migrate/create_#{table_name}.rb"
end
def create_model_file

View file

@ -179,6 +179,27 @@ class AddDetailsToProducts < ActiveRecord::Migration
end
```
If the migration name is of the form "CreateXXX" and is
followed by a list of column names and types then a migration creating the table
XXX with the columns listed will be generated. For example:
```bash
$ rails generate migration CreateProducts name:string part_number:string
```
generates
```ruby
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :name
t.string :part_number
end
end
end
```
As always, what has been generated for you is just a starting point. You can add
or remove from it as you see fit by editing the
`db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb` file.

View file

@ -172,8 +172,19 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
end
end
def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove
migration = "create_books"
def test_create_table_migration
run_generator ["create_books", "title:string", "content:text"]
assert_migration "db/migrate/create_books.rb" do |content|
assert_method :change, content do |change|
assert_match(/create_table :books/, change)
assert_match(/ t\.string :title/, change)
assert_match(/ t\.text :content/, change)
end
end
end
def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove_or_create
migration = "delete_books"
run_generator [migration, "title:string", "content:text"]
assert_migration "db/migrate/#{migration}.rb" do |content|
@ -182,7 +193,7 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
end
end
end
def test_properly_identifies_usage_file
assert generator_class.send(:usage_path)
end