提交 20e04157 编写于 作者: S Sammy Larbi

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.
上级 bb9f8312
## 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.
......@@ -8,13 +8,14 @@ class MigrationGenerator < Base # :nodoc:
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 @@ def set_local_assigns!
set_index_names
end
when /^create_(.+)/
@table_name = $1.pluralize
@migration_template = "create_table_migration.rb"
end
end
......@@ -44,7 +48,10 @@ def index_name_for(attribute)
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)
......
......@@ -15,7 +15,7 @@ class ModelGenerator < Base # :nodoc:
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
......
......@@ -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.
......
......@@ -172,8 +172,19 @@ def test_create_join_table_migration
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 @@ def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove
end
end
end
def test_properly_identifies_usage_file
assert generator_class.send(:usage_path)
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册