Rails Migrations: Populating/Updating Data

Recently I added the ability to set a publish date to blog posts. It would allow me to set a date in the future, and have the website not display the post until that date. The code I used to accomplish this can be found both here and here. That part was straight forward. The problem I ran into was setting the published_at date on all my previous posts. Just running the migration to add the published_at column set the value to nil on every post in the database. That wouldn't work, it would ruin the archives page, since everything that was once created_at is now published_at.

It only took a couple tries to come up with a solution. The main was adding the published_at column, and populating it right away with a date. Pretty or otherwise, here's the migration code:

class AddPublishedAtToPosts < ActiveRecord::Migration
  def self.up
    add_column :posts, :published_at, :datetime

    Post.all.each do |post|
      post.published_at = post.created_at
      post.save

      puts "'#{post.title}' published date updated to #{post.created_at}\n"
    end
  end

  def self.down
    remove_column :posts, :published_at
  end
end

A Simple problem, one of a few simple solutions, hopefully this saves someone a headache.

An even more simple solution, but note, I haven't actually tested this, so it would be wise to try it on some worthless data first, to make sure it works.

Post.all.each { |post| post.update_attribute :published_at, post.created_at }

The differences being, one line of code, as opposed to six, and no visual feedback.

Filed in Tutorials.