On 4 March 2010 17:30, Hassan S. [email protected]
wrote:
Similarly, you can now no longer alter your models, because some
migrations rely on the operation of the model at that “point in time”
Likewise, sorry, that makes zero sense to me. I can’t alter a model
because it was altered before? What??
Maybe an example would help…
Yesterday I created this model and it’s migration:
class Post < ActiveRecord::Base
end
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.string :summary
t.string :user_id
t.timestamps
end
default record for Posts
Post.reset_column_information
Post.create(:name => “My First Post”, :user_id => 1)
end
def self.down
drop_table :posts
end
end
Today I decide that I need to have an “expired flag” on my posts, and
it’s required, so I create a new migration and edit my model:
class Post < ActiveRecord::Base
validates_presence_of :expires
end
class AlterPostsAddExpired < ActiveRecord::Migration
def self.up
add_column :posts, :expires, :datetime
end
def self.down
remove_column :posts, :expires
end
end
But now, when I roll back my migrations and try to roll them forward
again, the “create” breaks because the “point in time” Post record
didn’t require an “expires” value (or indeed, even have a field for
it!).
As Rob says, the way around this is to duplicate the model code (or at
least the minimum you need to achieve your result) in the migration -
but this is a smelly, non-DRY, and non-testable way of putting data in
the tables (remember where I said it was “deliberately awkward” to do)
- when the alternative is to use a seed or seed-fu (like, 30 seconds
work), I can’t believe you’re making me go through these hoops to show
you how bad a practice it is to put data in your migrations
:-/