Ruby On Rails : Order of invocation of migration / model generator matters in initial design

If you are planning or about to start the development of new Rails app you definitely have to write migrations. There are straight forward steps to set the initial architecture of the Rails app on which the future development gonna depend. However, lack of prior knowledge about how $ rake db:migrate parse and apply migration, you might encounter some unexpected errors and fail to complete the complete schema generation.

Suppose that you are going to create a “Online shopping” application and you have the following relationship of models.

ERR diagram of Lost and found app

ERR diagram of Online shopping app

Picture -- belongs_to --> Item
SpecialProperties -- belongs_to --> Item
Item -- belongs_to --> ItemType
ItemType -- belongs --> Category

In the example above the order in which you invoke the Rails‘s migration generator or model generator must be as follows

# In the beginning, need to create Category as ItemType depends on it
$ rails g model Category title:string

# Now create ItemType as Item depends on it
$ rails g model ItemType title:string category:references

# Now create Item as Picture and SpecialProperties depend on this
$ rails g model Item title:string item_type:references

# Then you may create others

Reason:

The main reason behind this is, when you invoke the model / migration generator it creates migration files in db/migrate with file-names with time-stamp as prefix.

Migration files inside db/migrate

Migration files inside db/migrate

When you invoke the  $ rake db:migrate it reads all the files and arrange according to the time-stamp in ascending order.

That is, if you have generated migration file to create ‘Item` before ‘ItemType‘ then you are in trouble as the rake task will try to create table and add foreign key and get error as the depended table ‘ItemType‘ does not exist yet.

Conclusion:

The order of invocation of model / migration generator matters, so be careful. To fix this you also can exchange just the time-stamps in the order they are supposed to be. Or simply start over if you enjoy.

Error Log (add_foreign_key StandardError: Mysql2::Error: Can’t create table  ) :

shiva@ubuntu:~/projects/onelineshopping (OS-2)$ rake db:migrate
== 20150816095531 CreateItemTypes: migrating ==================================
-- create_table(:item_types)
 -> 0.0076s
-- add_foreign_key(:item_types, :categories)
rake aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Can't create table 'onelineshopping.#sql-4c3_3d' (errno: 150): ALTER TABLE `item_types` ADD CONSTRAINT `fk_rails_3efc45d56e`
FOREIGN KEY (`category_id`)
 REFERENCES `categories` (`id`)
/home/shiva/.rvm/gems/ruby-2.1.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:299:in `query'
/home/shiva/.rvm/gems/ruby-2.1.1/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract_mysql_adapter.rb:299:in `block in execute'

2 thoughts on “Ruby On Rails : Order of invocation of migration / model generator matters in initial design

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s