开发者

Rails 3 - What's wrong with this migration?

I have an app running. I want to create a UserNotifications migration that belongs_to user. But the migration keeps erroring.

class CreateUserNotifications < ActiveRecord::Migration
  def self.up
    create_table :user_notifications do |t|
      t.integer :user_id
      t.boolean :notify_news, :default => true
      t.boolean :notify_research, :default => true
      t.timestamps

    end

    # Ensure Existi开发者_StackOverflow中文版ng users have a notification setting
    User.all.each do |u|
      UserNotification.create_by_user_id(u.id)
      user.save
    end

add_index :user_notifications, :user_id
  end

  def self.down
    drop_table :user_notifications
  end
end

To make sure I'm asking a clear q, here is the model info:

class User < ActiveRecord::Base
  has_one :user_notification, :dependent => :destroy

class UserNotification < ActiveRecord::Base  
  belongs_to :user

ERROR:

$ rake db:migrate
(in /Users/bhellman/Sites/cline)
==  CreateUserNotifications: migrating ========================================
-- create_table(:user_notifications)
NOTICE:  CREATE TABLE will create implicit sequence "user_notifications_id_seq" for serial column "user_notifications.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "user_notifications_pkey" for table "user_notifications"
   -> 0.2942s
rake aborted!
An error has occurred, this and all later migrations canceled:

undefined method `create_by_user_id' for UserNotification(Table doesn't exist):Class

Thanks for taking a look


Try this

User.all.each do |u|
  UserNotification.create(:user_id => u.id)
end

The error could be due to the DB schema rails is referring to isn't up to date (and therefore doesn't respond to the dynamic methods). You might also want to try

UserNotification.reset_column_information

before using create_by_user_id (i.e. above the block)


Your self.up code is being run in a database transaction. So when you're trying to run your create methods, the new table isn't officially in existence yet. You can move it to a separate migration, but there is a much better way.

You should build a rake task to do this, and keep it out of the migration entirely. I've written a blog post about this:

Adding Columns and Default Data to Existing Models

The section "More Complex Default Values" goes over the reasons you shouldn't put code like this in a migration. The main reason is that migrations "rot" over time - as your code base changes, older migrations stop working.

If you have any questions, let me know. I hope this helps!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜