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