4 votes

Comment puis-je contourner le nom du modèle à l'intérieur d'une migration ?

En Guide de migration vers Rails suggère de créer un faux modèle à l'intérieur de la migration, si vous avez besoin d'opérer sur les données de la base de données, comme par exemple :

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

Le fait est qu'à l'intérieur de la AddFuzzToProduct le nom du modèle de produit sera AddFuzzToProduct::Product . Je me trouve dans la situation suivante :

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

Le fait est qu'à l'intérieur de la each pour le profil de l'étudiant, l'utilisateur est nul. Après avoir activé le logger, je peux voir que Rails essaie de faire la requête suivante :

 RemoveFirstNameFromStudentProfile::User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."profile_id" = 30 AND "users"."profile_type" = 'RemoveFirstNameFromStudentProfile::StudentProfile' LIMIT 1

Bien entendu, il est possible de remédier à ce problème en déplaçant le fichier User y StudentProfile d'un niveau, comme dans :

  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

Ma question est la suivante : est-ce que le fait de déplacer les définitions des faux modèles en dehors de la déclaration de la migration peut me poser des problèmes ? Y a-t-il quelque chose qui m'échappe ? Pourquoi les gars de l'équipe Rails les ont-ils déclarés à l'intérieur de la classe de migration ?

2voto

Mars Points 1061

Avec Ruby, vous pouvez toujours référencer une classe ou un module comme étant de premier niveau en le préfixant avec :: .

Votre exemple de migration ressemblerait à ceci :

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

  ...
end

1voto

abhas Points 3619

Non, cela ne vous posera aucun problème car vous n'ajoutez pas de nouvelles colonnes et vous ne les mettez pas à jour.

L'équipe Rails l'a déclaré à l'intérieur de la migration parce qu'elle ajoutait une nouvelle colonne et la mettait à jour, mais si le modèle est à l'extérieur, il essaiera de valider cette colonne, ce qui n'est pas possible car elle n'existait pas, elle a juste été ajoutée lors de la migration. C'est pour cette raison qu'ils ont créé des modèles locaux dans la migration uniquement. Utiliser des modèles dans vos migrations

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X