Permalink
Browse files

Merge pull request #6956 from lexmag/ref_migration_generator

Add references statements to migration generator
  • Loading branch information...
2 parents 22bc12e + 07ebc53 commit bbc08c759c13d654621c1eb0659f3bdd6a66dfd5 @rafaelfranca rafaelfranca committed Jul 8, 2012
@@ -2,30 +2,42 @@ class <%= migration_class_name %> < ActiveRecord::Migration
<%- if migration_action == 'add' -%>
def change
<% attributes.each do |attribute| -%>
+ <%- if attribute.reference? -%>
+ add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
+ <%- else -%>
add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
<%- if attribute.has_index? -%>
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
<%- end -%>
+ <%- end -%>
<%- end -%>
end
<%- else -%>
def up
<% attributes.each do |attribute| -%>
- <%- if migration_action -%>
- <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %>
+<%- if migration_action -%>
+ <%- if attribute.reference? -%>
+ remove_reference :<%= table_name %>, :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
+ <%- else -%>
+ remove_column :<%= table_name %>, :<%= attribute.name %>
<%- end -%>
<%- end -%>
+<%- end -%>
end
def down
<% attributes.reverse.each do |attribute| -%>
- <%- if migration_action -%>
+<%- if migration_action -%>
+ <%- if attribute.reference? -%>
+ add_reference :<%= table_name %>, :<%= attribute.name %><%= attribute.inject_options %>
+ <%- else -%>
add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
<%- if attribute.has_index? -%>
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
<%- end -%>
<%- end -%>
<%- end -%>
+<%- end -%>
end
<%- end -%>
-end
+end
@@ -111,6 +111,7 @@ Active Record provides methods that perform common data definition tasks in a
database independent way (you'll read about them in detail later):
* +add_column+
+* +add_reference+
* +add_index+
* +change_column+
* +change_table+
@@ -120,6 +121,7 @@ database independent way (you'll read about them in detail later):
* +remove_column+
* +remove_index+
* +rename_column+
+* +remove_reference+
If you need to perform tasks specific to your database (for example create a
"foreign key":#active-record-and-referential-integrity constraint) then the
@@ -332,6 +334,51 @@ NOTE: The generated migration file for destructive migrations will still be
old-style using the +up+ and +down+ methods. This is because Rails needs to know
the original data types defined when you made the original changes.
+Also the generator accepts column type as +references+(also available as +belongs_to+), for instance
+
+<shell>
+$ rails generate migration AddUserRefToProducts user:references
+</shell>
+
+generates
+
+<ruby>
+class AddUserRefToProducts < ActiveRecord::Migration
+ def change
+ add_reference :products, :user, :index => true
+ end
+end
+</ruby>
+
+This migration will create a user_id column and appropriate index.
+
+h4. Supported type modifiers
+
+You can also specify some options just after the field type between curly braces. You can use the
+following modifiers:
+
+* +limit+ Sets the maximum size of the +string/text/binary/integer+ fields
+* +precision+ Defines the precision for the +decimal+ fields
+* +scale+ Defines the scale for the +decimal+ fields
+* +polymorphic+ Adds a +type+ column for +belongs_to+ associations
+
+For instance running
+
+<shell>
+$ rails generate migration AddDetailsToProducts price:decimal{5,2} supplier:references{polymorphic}
+</shell>
+
+will produce a migration that looks like this
+
+<ruby>
+class AddDetailsToProducts < ActiveRecord::Migration
+ def change
+ add_column :products, :price, :precision => 5, :scale => 2
+ add_reference :products, :user, :polymorphic => true, :index => true
+ end
+end
+</ruby>
+
h3. Writing a Migration
Once you have created your migration using one of the generators it's time to
View
@@ -1,5 +1,16 @@
## Rails 4.0.0 (unreleased) ##
+* The migration generator will now produce AddXXXToYYY/RemoveXXXFromYYY migrations with references statements, for instance
+
+ rails g migration AddReferencesToProducts user:references supplier:references{polymorphic}
+
+ will generate the migration with:
+
+ add_reference :products, :user, index: true
+ add_reference :products, :supplier, polymorphic: true, index: true
+
+ *Aleksey Magusev*
+
* Allow scaffold/model/migration generators to accept a `polymorphic` modifier
for `references`/`belongs_to`, for instance
@@ -76,6 +76,23 @@ def test_remove_migration_with_attributes
end
end
+ def test_remove_migration_with_references_options
+ migration = "remove_references_from_books"
+ run_generator [migration, "author:belongs_to", "distributor:references{polymorphic}"]
+
+ assert_migration "db/migrate/#{migration}.rb" do |content|
+ assert_method :up, content do |up|
+ assert_match(/remove_reference :books, :author/, up)
+ assert_match(/remove_reference :books, :distributor, polymorphic: true/, up)
+ end
+
+ assert_method :down, content do |down|
+ assert_match(/add_reference :books, :author, index: true/, down)
+ assert_match(/add_reference :books, :distributor, polymorphic: true, index: true/, down)
+ end
+ end
+ end
+
def test_add_migration_with_attributes_and_indices
migration = "add_title_with_index_and_body_to_posts"
run_generator [migration, "title:string:index", "body:text", "user_id:integer:uniq"]
@@ -138,6 +155,18 @@ def test_add_migration_with_attributes_index_declaration_and_attribute_options
end
end
+ def test_add_migration_with_references_options
+ migration = "add_references_to_books"
+ run_generator [migration, "author:belongs_to", "distributor:references{polymorphic}"]
+
+ assert_migration "db/migrate/#{migration}.rb" do |content|
+ assert_method :change, content do |up|
+ assert_match(/add_reference :books, :author, index: true/, up)
+ assert_match(/add_reference :books, :distributor, polymorphic: true, index: 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"]

0 comments on commit bbc08c7

Please sign in to comment.