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!
精彩评论