Utiliser la construction avec une association has_one dans les rails

Dans cet exemple, je crée un user sans profile , puis crée ultérieurement un profile pour cet utilisateur. J’ai essayé d’utiliser build avec une association has_one mais qui a explosé. La seule façon dont je vois ce travail consiste à utiliser has_many . L’ user est censé avoir au plus un seul profile .

J’ai essayé ceci. J’ai:

 class User < ActiveRecord::Base has_one :profile end class Profile < ActiveRecord::Base belongs_to :user end 

Mais quand je fais:

 user.build_profile 

Je reçois l’erreur:

 ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'profiles.user_id' in 'where clause': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) LIMIT 1 

Y a-t-il un moyen dans les rails d’avoir 0 ou 1 association?

La signature de la méthode de build est différente pour les associations has_one et has_many .

 class User < ActiveRecord::Base has_one :profile has_many :messages end 

La syntaxe de has_many pour l'association has_many :

 user.messages.build 

La syntaxe de has_one pour l'association has_one :

 user.build_profile # this will work user.profile.build # this will throw error 

Lisez la documentation de l' association has_one pour plus de détails.

Regardez bien le message d’erreur. Il vous user_id colonne user_id n’est pas requirejse dans la table de profil . Définir les relations dans le modèle n’est qu’une partie de la réponse.

Vous devez également créer une migration qui ajoute la colonne user_id à la table de profil. Rails s’attend à ce que ce soit là et si ce n’est pas le cas, vous ne pouvez pas accéder au profil.

Pour plus d’informations, consultez ce lien:

Principes de base de l’association

Selon le cas d’utilisation, il peut être pratique de regrouper la méthode et de créer automatiquement l’association lorsqu’elle est introuvable.

 old_profile = instance_method(:profile) define_method(:profile) do old_profile.bind(self).call || build_profile end 

appeler maintenant la méthode #profile renvoie le profil associé ou #profile une nouvelle instance.

source: lorsque vous appliquez un patch à une méthode, pouvez-vous appeler la méthode substituée à partir de la nouvelle implémentation?

Ce devrait être un has_one . Si build ne fonctionne pas, vous pouvez simplement utiliser new :

 ModelName.new( :owner => @owner ) 

est le même que

 @owner.model_names.build