提交 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) ## ## 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 * Fix bug that raises the wrong exception when the exception handled by PostgreSQL adapter
doesn't respond to `#result`. doesn't respond to `#result`.
Fixes #8617. Fixes #8617.
...@@ -362,7 +372,7 @@ ...@@ -362,7 +372,7 @@
deprecated and removed in future versions of Rails. deprecated and removed in future versions of Rails.
*Amparo Luna + Guillermo Iguaran* *Amparo Luna + Guillermo Iguaran*
* `after_commit` and `after_rollback` now validate the `:on` option and raise an `ArgumentError` * `after_commit` and `after_rollback` now validate the `:on` option and raise an `ArgumentError`
if it is not one of `:create`, `:destroy` or `:update` if it is not one of `:create`, `:destroy` or `:update`
...@@ -1549,4 +1559,5 @@ ...@@ -1549,4 +1559,5 @@
*Aaron Patterson* *Aaron Patterson*
Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/activerecord/CHANGELOG.md) for previous changes. 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: ...@@ -8,13 +8,14 @@ class MigrationGenerator < Base # :nodoc:
def create_migration_file def create_migration_file
set_local_assigns! set_local_assigns!
validate_file_name! validate_file_name!
migration_template "migration.rb", "db/migrate/#{file_name}.rb" migration_template @migration_template, "db/migrate/#{file_name}.rb"
end end
protected protected
attr_reader :migration_action, :join_tables attr_reader :migration_action, :join_tables
def set_local_assigns! def set_local_assigns!
@migration_template = "migration.rb"
case file_name case file_name
when /^(add|remove)_.*_(?:to|from)_(.*)/ when /^(add|remove)_.*_(?:to|from)_(.*)/
@migration_action = $1 @migration_action = $1
...@@ -26,6 +27,9 @@ def set_local_assigns! ...@@ -26,6 +27,9 @@ def set_local_assigns!
set_index_names set_index_names
end end
when /^create_(.+)/
@table_name = $1.pluralize
@migration_template = "create_table_migration.rb"
end end
end end
...@@ -44,7 +48,10 @@ def index_name_for(attribute) ...@@ -44,7 +48,10 @@ def index_name_for(attribute)
end end
private private
def attributes_with_index
attributes.select { |a| !a.reference? && a.has_index? }
end
def validate_file_name! def validate_file_name!
unless file_name =~ /^[_a-z0-9]+$/ unless file_name =~ /^[_a-z0-9]+$/
raise IllegalMigrationNameError.new(file_name) raise IllegalMigrationNameError.new(file_name)
......
...@@ -15,7 +15,7 @@ class ModelGenerator < Base # :nodoc: ...@@ -15,7 +15,7 @@ class ModelGenerator < Base # :nodoc:
def create_migration_file def create_migration_file
return unless options[:migration] && options[:parent].nil? 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 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 end
def create_model_file def create_model_file
......
...@@ -179,6 +179,27 @@ class AddDetailsToProducts < ActiveRecord::Migration ...@@ -179,6 +179,27 @@ class AddDetailsToProducts < ActiveRecord::Migration
end 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 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 or remove from it as you see fit by editing the
`db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb` file. `db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb` file.
......
...@@ -172,8 +172,19 @@ def test_create_join_table_migration ...@@ -172,8 +172,19 @@ def test_create_join_table_migration
end end
end end
def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove def test_create_table_migration
migration = "create_books" 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"] run_generator [migration, "title:string", "content:text"]
assert_migration "db/migrate/#{migration}.rb" do |content| 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 ...@@ -182,7 +193,7 @@ def test_should_create_empty_migrations_if_name_not_start_with_add_or_remove
end end
end end
end end
def test_properly_identifies_usage_file def test_properly_identifies_usage_file
assert generator_class.send(:usage_path) assert generator_class.send(:usage_path)
end end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册