如何在迁移中解决模型的名称?

时间:2012-09-24 13:17:29

标签: ruby-on-rails database activerecord migration

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

当然,可以通过将UserStudentProfile向上移动一级来解决此问题,例如:

  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团队的人员会在迁移类中声明它们?

2 个答案:

答案 0 :(得分:2)

使用Ruby,您始终可以通过在::前添加前缀来引用类或模块作为顶级。

您的示例迁移将如下所示:

class AddFuzzToProduct < ActiveRecord::Migration
  class ::Product < ActiveRecord::Base
  end

  ...
end

答案 1 :(得分:1)

不,它不会对您造成任何问题,因为您没有添加任何新列并进行更新。

Rails团队已经在迁移中声明了它,因为他们正在添加一个新列,然后更新它,但如果Model在外面并且它将尝试验证那个不可能的列,因为它不在那里,它只是添加了移民。由于这个原因,他们在迁移中创建了本地模型,只是为了更多阅读Using Models in your migrations