Migration adds a column, can't set a value for it

I've got a migration that adds a column then sets the value for one of the records:

  def self.up     add_column :publish_property_lists, :preview_page_header, :string     if p = PublishPropertyList.find(:first, :conditions => "default_properties IS TRUE")       p.update_attribute :preview_page_header, "Preview Your Video Entry"     end   end

However after running the migration, preview_page_header is still null in the database. I thew a puts statement inside the if to make sure it's getting there, and it is. So why isn't the record being updated?

Pat

I've got a migration that adds a column then sets the value for one of the records:

  def self.up     add_column :publish_property_lists, :preview_page_header, :string

PublishPropertyList.reset_column_information

    if p = PublishPropertyList.find(:first, :conditions => "default_properties IS TRUE")       p.update_attribute :preview_page_header, "Preview Your Video Entry"     end   end

However after running the migration, preview_page_header is still null in the database. I thew a puts statement inside the if to make sure it's getting there, and it is. So why isn't the record being updated?

Pat

ActiveRecord needs to be told to take a new look at the table since you changed it.

-Rob

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

It gets weirder (for me). I thought maybe it was a transaction issue, so I split the migration out into two separate steps. The first migration adds the column. The second migration finds the record and updates it. I took the conditional out of the second migration as well, so I know that it's finding and updating a record. Still, the database doesn't reflect that.

If I create a record with attributes, it's fine. I just can't update it from a migration. What gives?

Pat

Okay looking at the logs, the migration updates all the existing values and commits it. So say the record has the name "foo", the logs show:

  PublishPropertyList Load (0.000552) SELECT * FROM publish_property_lists WHERE (default_properties IS TRUE) LIMIT 1   SQL (0.000152) BEGIN   PublishPropertyList Update (0.000452) UPDATE publish_property_lists SET `name` = 'foo' WHERE id = 1   SQL (0.000098) COMMIT

Obviously that's not very helpful...I don't need to update the record with the attributes it already has, but rather need to update its new attributes. I'm really confused here.

Pat

My previous email is still valid (reset_column_information), but you probably also have to make the condition valid from the point of view from SQL.

Try this:

p = PublishPropertyList.find(:first, :conditions => ["default_properties = ?", true])

This should work for any database regardless of whether booleans are modeled as 0/1 or true/false.

In any case the SQL fragment "where default_properties IS TRUE" is quite likely not equivalent to "where default_properties = 1" or "where default_properties = true" (note "=" rather than "IS").

-Rob

Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com

It turns out I need to add PublishPropertyList.reset_column_information

Now that behavior makes a little bit of sense when I do the full migration (0-final). When I create the record, Rails loads PublishPropertyList into the namespace. When I go to update it later on, it has it cached along with the columns. So I have to reset the column info.

It'd make a lot more sense if Rails threw a method missing error, because that's essentially what it thinks is going on. Oh well.

Pat