Hola (gran novato de Rails aquí), tengo los siguientes modelos:
class Shop < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :title, :user_id, :message => "is already being used"
end
y
class User < ActiveRecord::Base
has_one :shop, :dependent => :destroy
end
Cuando estoy a punto de crear una nueva tienda, aparece el siguiente error:
private method `create' called for nil:NilClass
Este es mi controlador:
@user = current_user
@shop = @user.shop.create(params[:shop])
He probado diferentes variaciones leyendo guías y tutoriales aquí y allá, pero estoy más confundido que antes y no puedo hacer que funcione. Cualquier ayuda será muy apreciada.
ruby-on-rails
Neko
fuente
fuente
@user.build_shop(params)
Respuestas:
En primer lugar, aquí se explica cómo hacer lo que quiere:
Ahora, he aquí por qué su versión no funcionó:
Probablemente pensó que este trabajo podría, porque si el usuario tenía una
has_many
relación con la tienda,@user.shops.create(params[:shop])
sería trabajar. Sin embargo, existe una gran diferencia entrehas_many
relaciones yhas_one
relaciones:Con una
has_many
relación,shops
devuelve un objeto de colección ActiveRecord, que tiene métodos que puede usar para agregar y eliminar tiendas de un usuario. Uno de esos métodos escreate
, que crea una nueva tienda y la agrega al usuario.Con una
has_one
relación, no recupera tal objeto de colección, sino simplemente el objeto Tienda que pertenece al usuario, o nulo si el usuario aún no tiene una tienda. Dado que ni Shop objects ni nil tienen uncreate
método, no se puede usar decreate
esta manera con lashas_one
relaciones.fuente
@user.create_shop(params[:shop])
. Vea los métodos agregados por has_one .Una forma más concisa de hacer esto es con:
Vea los métodos agregados por has_one en las guías de Ruby on Rails.
fuente
@user.create_shop(params[:shop_one_info])
, creará shop_one, PERO si lo ejecuta@user.create_shop(params[:shop_two_info])
, eliminará la primera tienda y creará la segunda.@user.build_shop(params)
Dos formas más si lo desea en
save
lugar decreate
:fuente
Solo para agregar a las respuestas anteriores:
La sintaxis anterior crea un nuevo registro, pero posteriormente elimina un registro similar existente.
Alternativamente, si no desea activar eliminar devolución de llamada
Este hilo puede ser útil. haga clic aquí
fuente