4

Rails 移行ガイドでは、データベースからのデータを操作する必要がある場合、次のように、移行内に偽のモデルを作成することをお勧めします。

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クラス内で、製品モデルの名前が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を 1 レベル上に移動することで修正できます。

  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 チームの担当者が移行クラス内でそれらを宣言したのはなぜですか?

4

2 に答える 2

2

Ruby では、クラスまたはモジュールに接頭辞を付けることで、いつでもトップレベルとして参照できます::

移行の例は次のようになります。

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

  ...
end
于 2012-10-01T04:03:19.883 に答える
1

いいえ、新しい列を追加して更新していないため、問題は発生しません。

Railsチームは、新しい列を追加してから更新していたため、移行内で宣言しましたが、モデルが外部にあり、その列が存在しないため不可能な列を検証しようとする場合、移行に追加されました. そのため、彼らは移行でのみローカル モデルを作成しました。詳細については、移行でのモデルの使用をお読みください。

于 2012-09-27T12:26:17.723 に答える