ruby-on-rails - references - rails has_many through example
Usar build con una asociaciĆ³n has_one en rieles (4)
En este ejemplo, creo un user
sin profile
, luego creo un profile
para ese usuario. Intenté usar build con una asociación has_one
, pero explotó. La única forma en que veo que esto funciona es usando has_many
. Se supone que el user
solo tiene como máximo un profile
.
He estado intentando esto. Yo tengo:
class User < ActiveRecord::Base
has_one :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
end
Pero cuando lo hago:
user.build_profile
Me sale el error:
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column ''profiles.user_id'' in ''where clause'': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) LIMIT 1
¿Hay alguna manera de barajar para tener 0 o 1 asociación?
Debería ser un has_one
. Si la build
no funciona, puedes usar new
:
ModelName.new( :owner => @owner )
es lo mismo que
@owner.model_names.build
Eche un buen vistazo al mensaje de error. Le dice que no tiene columna user_id
requerida en la tabla de perfil . Establecer las relaciones en el modelo es solo una parte de la respuesta.
También necesita crear una migración que agregue la columna user_id
a la tabla de perfil. Rails espera que esté allí y, si no es así, no puede acceder al perfil.
Para obtener más información, consulte este enlace:
La firma del método de build
es diferente para has_one
y has_one
asociaciones.
class User < ActiveRecord::Base
has_one :profile
has_many :messages
end
La sintaxis de compilación para la asociación has_many
:
user.messages.build
La sintaxis de has_one
para la asociación has_one
:
user.build_profile # this will work
user.profile.build # this will throw error
Lea la documentation asociación has_one
para más detalles.
Según el caso de uso, puede ser conveniente ajustar el método y crear automáticamente la asociación cuando no se encuentre.
old_profile = instance_method(:profile)
define_method(:profile) do
old_profile.bind(self).call || build_profile
end
ahora llamar al método #profile
devolverá el perfil asociado o creará una nueva instancia.
fuente: Cuando mono parcheando un método, ¿puede llamar al método reemplazado de la nueva implementación?