Rails migration guide,建议您在迁移过程中创建一个虚拟模型,如果您需要对数据库中的数据进行操作,例如:
class AddFuzzToProduct < ActiveRecord::Migration
class Product < ActiveRecord::Base
end
def change
add_column :products, :fuzz, :string
Product.reset_column_information
Product.all.each do |product|
product.update_attributes!(:fuzz => 'fuzzy')
end
end
end
问题是,在AddFuzzToProduct
类中,Product模型的名称将为AddFuzzToProduct::Product
。我有以下情况:
class RemoveFirstNameFromStudentProfile < ActiveRecord::Migration
class StudentProfile < ActiveRecord::Base
has_one :user,:as => :profile
end
class User < ActiveRecord::Base
belongs_to :profile,:polymorphic => true,:dependent => :destroy
end
def up
StudentProfile.all.each do |student|
# I need to do some work on the user object as well as on the student object
user = student.user
... # do some stuff on the user object
end
end
end
问题是,在学生档案的each
区块内,用户是零。激活记录器后,我可以看到Rails正在尝试执行以下查询:
RemoveFirstNameFromStudentProfile::User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."profile_id" = 30 AND "users"."profile_type" = 'RemoveFirstNameFromStudentProfile::StudentProfile' LIMIT 1
当然,可以通过将User
和StudentProfile
向上移动一级来解决此问题,例如:
class StudentProfile < ActiveRecord::Base
has_one :user,:as => :profile
end
class User < ActiveRecord::Base
belongs_to :profile,:polymorphic => true,:dependent => :destroy
end
class RemoveFirstNameFromStudentProfile < ActiveRecord::Migration
def up
StudentProfile.all.each do |student|
...
end
end
end
我的问题是:可以在迁移声明之外移动仿模型的定义会对我造成任何问题吗?这里有什么我想念的吗?为什么Rails团队的人员会在迁移类中声明它们?
答案 0 :(得分:2)
使用Ruby,您始终可以通过在::
前添加前缀来引用类或模块作为顶级。
您的示例迁移将如下所示:
class AddFuzzToProduct < ActiveRecord::Migration
class ::Product < ActiveRecord::Base
end
...
end
答案 1 :(得分:1)
不,它不会对您造成任何问题,因为您没有添加任何新列并进行更新。
Rails团队已经在迁移中声明了它,因为他们正在添加一个新列,然后更新它,但如果Model在外面并且它将尝试验证那个不可能的列,因为它不在那里,它只是添加了移民。由于这个原因,他们在迁移中创建了本地模型,只是为了更多阅读Using Models in your migrations