Olá (grande novato em Rails aqui), eu tenho os seguintes modelos:
class Shop < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :title, :user_id, :message => "is already being used"
end
e
class User < ActiveRecord::Base
has_one :shop, :dependent => :destroy
end
Quando estou prestes a criar uma nova loja, recebo o seguinte erro:
private method `create' called for nil:NilClass
Este é meu controlador:
@user = current_user
@shop = @user.shop.create(params[:shop])
Eu tentei variações diferentes lendo guias e tutoriais aqui e ali, mas estou mais confuso do que antes e não consigo fazer funcionar. Qualquer ajuda seria muito apreciada.
ruby-on-rails
Neko
fonte
fonte
@user.build_shop(params)
Respostas:
Em primeiro lugar, aqui está como fazer o que você deseja:
Veja por que sua versão não funcionou:
Você provavelmente pensou que este trabalho poder, porque se o usuário tinha uma
has_many
relação Shop,@user.shops.create(params[:shop])
iria trabalhar. No entanto, há uma grande diferença entrehas_many
relações ehas_one
relações:Com uma
has_many
relação,shops
retorna um objeto de coleção ActiveRecord, que possui métodos que você pode usar para adicionar e remover lojas de / para um usuário. Um desses métodos écreate
, que cria uma nova loja e a adiciona ao usuário.Com uma
has_one
relação, você não recebe de volta esse objeto de coleção, mas simplesmente o objeto Loja que pertence ao usuário - ou nulo se o usuário ainda não tiver uma loja. Uma vez que nem objetos Shop nem nil têm umcreate
método, você não pode usarcreate
essa forma comhas_one
relações.fonte
@user.create_shop(params[:shop])
. Veja os métodos adicionados por has_one .Uma maneira mais concisa de fazer isso é com:
Veja os métodos adicionados por has_one nos guias do Ruby on Rails.
fonte
@user.create_shop(params[:shop_one_info])
lo, criará shop_one, MAS se você executar,@user.create_shop(params[:shop_two_info])
ele excluirá a primeira loja e criará a segunda.@user.build_shop(params)
Mais duas maneiras, se você quiser, em
save
vez decreate
:fonte
Apenas para adicionar às respostas acima -
A sintaxe acima cria um novo registro, mas subsequentemente exclui um registro existente semelhante.
Como alternativa, se você não quiser acionar o callback delete
Este tópico pode ser útil. Clique aqui
fonte