views:

1005

answers:

1

I created number of migrations starting with a definition for a Posts table.

class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.column "title", :string, :limit => 100, :default => "",  :null => false
      t.column "content", :text, :null => false
      t.column "author", :string, :limit => 100, :default => 0,  :null => false
      t.column "category", :string, :limit => 20, :default => "",  :null => false
      t.column "status", :string, :limit => 20, :default => "",  :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :posts
  end
end

And another one for a Users table in which I load some data for a default user after creating the table.

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.column "username", :string,     :limit => 25, :default => "",   :null => false
      t.column "hashed_password", :string,  :limit => 40, :default => "", :null => false
      t.column "first_name", :string,   :limit => 25, :default => "",   :null => false
      t.column "last_name", :string,    :limit => 40, :default => "",   :null => false
      t.column "email", :string,        :limit => 50, :default => "",   :null => false
      t.column "display_name", :string, :limit => 25, :default => "",   :null => false
      t.column "user_level", :integer,  :limit => 3,  :default => 0,   :null => false
      t.timestamps
    end
    user = User.create(:username => 'bopeep',
      :hashed_password => 'bopeep',
      :first_name => 'Bo',
      :last_name => 'Peep',
      :email => '[email protected]',
      :display_name => 'Little Bo Peep',
      :user_level => 9)
  end

  def self.down
    drop_table :users
  end
end

Next I created a migration to alter the Posts table to rename the table to blog_posts. Here I also wanted to load a default blog post entry.

class AlterPosts < ActiveRecord::Migration
  def self.up
    rename_table :posts, :blog_posts
    change_column :blog_posts, :author, :integer, :default => 0, :null => false
    rename_column :blog_posts, :author, :author_id
    add_index :blog_posts, :author_id
    bopeep = User.find_by_username 'bopeep'
    BlogPost.create(:title => 'test', :content => 'test', :author_id => bopeep.id, :category => 'test', :status => 'ok')
  end

  def self.down
    remove_index :blog_posts, :author_id
    rename_table :blog_posts, :posts
    rename_column :posts, :author_id, :author
    change_column :posts, :author, :string, :limit => 100, :default => 0, :null => false
  end
end

But this generates an error:

uninitialized constant AlterPosts::BlogPost

How should I have loaded the default BlogPost instead of "BlogPost.create"?

+5  A: 

Separate your rename_table and your change/rename column migrations into another migration file.

I don't think the rename is committed until after the entire block goes through... and so therefore blog_posts does not exist yet.

phillc
Your explanation makes sense. I did what you said and created a LoadDefaultData migration file that kicks in after everything else. But I got an error: "uninitialized constant LoadDefaultData::BlogPost" for "BlogPost.create". This file has the same code I listed above: bopeep = User.find_by_username 'bopeep' BlogPost.create(:title => 'test', :content => 'test', :author_id => bopeep.id, :category => 'test', :status => 'ok')
pez_dispenser
and you already have a blog_post.rb model?If you go into script/console, and do aBlogPost.create(:title => 'test', :content => 'test', :author_id => bopeep.id, :category => 'test', :status => 'ok') do you get a database error or a rails error?
phillc
"and you already have a blog_post.rb model?" Oops. I thought the AlterPosts would have created the new model for blog_post. Instead I just found post.rb. Works now. Thanks a lot!
pez_dispenser