views:

74

answers:

3

I have a user model that checks to see if a value has changed before_save (by running User.zipcode_changed?). The idea is that this will queue up a delayed job if it has.

Problem is, when I migrate the app from scratch I get an error:

An error has occurred, all later migrations canceled:

undefined method `postcode_changed?' for #<User:0x105db6158>

Therefore, where should I be putting these? Is the model the wrong place?

+1  A: 

You say both zipcode_changed? and postcode_changed? in your question. What's the actual column name in your database - zipcode or postcode? ActiveRecord will only create the _changed? convenience method for the actual column name.

PreciousBodilyFluids
+4  A: 

When you checkout a new project from scratch, you shouldn't use migrations to build the database. You should use rake db:schema:load instead.

Let me show you why.

Let's assume you create a new Post model with a post table on migration 10. On migration 11, you execute some special elaborations on the Post model. After a while, you decide to drop the Post model and the post table because no longer required.

Six month later, you checkout the project from scratch. If you try to run rake db:migrate the migration 11 will fail complaining about missing model. It's true, the model has been removed many month before and it's no longer available.

Instead, if you run rake db:schema:load you'll initialize the database with the right schema version.

Talking about migrations, if you just created the postcode method and you are trying to use the _changed? magic method in the same migration, you need to reload the schema before.

class MigrationFile < ...
  self.up
    add_column :user, :postcode, :string

    User.all.each { |user| puts user.postcode_changed? }  # will fail 

    User.reset_column_information
    User.all.each { |user| puts user.postcode_changed? }  # now it works
  end
  ...
end
Simone Carletti
I should probably point out that this code is in the model, not the controller, but I see your point.
Neil Middleton
I never talked about the controller.
Simone Carletti
A: 

What you are doing is reasonable model code, but not so good in a migration.

Using model code in your migrations is problematic because of problems like this. I recommend sticking with SQL-oriented code.

ndp