Utilizzo di build con un’associazione has_one in rails

In questo esempio, creo un user senza profile , quindi creerò un profile per quell’utente. Ho provato a utilizzare build con un’associazione has_one ma è has_one . L’unico modo in cui vedo questo funziona sta usando has_many . Si suppone che l’ user abbia al massimo un solo profile .

Ho provato questo. Io ho:

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

Ma quando lo faccio:

 user.build_profile 

Ottengo l’errore:

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

C’è un modo in rail per avere 0 o 1 associazione?

La firma del metodo di build è diversa per has_one e has_many association.

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

La syntax di build per has_many associazione:

 user.messages.build 

La syntax di build per has_one associazione has_one :

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

Leggi la documentazione dell'associazione has_one per maggiori dettagli.

Dai un’occhiata al messaggio di errore. Ti sta dicendo che non hai richiesto la colonna user_id nella tabella del profilo . L’impostazione delle relazioni nel modello è solo una parte della risposta.

È inoltre necessario creare una migrazione che aggiunge la colonna user_id alla tabella del profilo. Rails si aspetta che questo sia lì e, in caso contrario, non è ansible accedere al profilo.

Per ulteriori informazioni si prega di dare un’occhiata a questo link:

Nozioni di base sull’associazione

A seconda del caso d’uso, può essere conveniente avvolgere il metodo e creare automaticamente l’associazione quando non trovata.

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

ora chiamando il metodo #profile restituirai il profilo associato o costruirai una nuova istanza.

fonte: quando esegui l’applicazione di patch su un metodo, puoi chiamare il metodo sottoposto a override dalla nuova implementazione?

Dovrebbe essere un has_one . Se build non funziona, puoi semplicemente usare new :

 ModelName.new( :owner => @owner ) 

equivale a

 @owner.model_names.build