Salut (énorme débutant Rails ici), j'ai les modèles suivants:
class Shop < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :title, :user_id, :message => "is already being used"
end
et
class User < ActiveRecord::Base
has_one :shop, :dependent => :destroy
end
Lorsque je suis sur le point de créer une nouvelle boutique, j'obtiens l'erreur suivante:
private method `create' called for nil:NilClass
Ceci est mon contrôleur:
@user = current_user
@shop = @user.shop.create(params[:shop])
J'ai essayé différentes variantes en lisant des guides et des tutoriels ici et là, mais je suis plus confus qu'avant et je n'arrive pas à le faire fonctionner. Toute aide serait grandement appréciée.
ruby-on-rails
Neko
la source
la source
@user.build_shop(params)
Réponses:
Tout d'abord, voici comment faire ce que vous voulez:
Voici maintenant pourquoi votre version n'a pas fonctionné:
Vous avez probablement pensé que cela pourrait fonctionner parce que si l'utilisateur avait une
has_many
relation avec la boutique,@user.shops.create(params[:shop])
cela fonctionnerait. Cependant, il y a une grande différence entre leshas_many
relations et leshas_one
relations:Avec une
has_many
relation,shops
renvoie un objet de collection ActiveRecord, qui a des méthodes que vous pouvez utiliser pour ajouter et supprimer des boutiques à / d'un utilisateur. L'une de ces méthodes consiste àcreate
créer une nouvelle boutique et à l'ajouter à l'utilisateur.Avec une
has_one
relation, vous ne récupérez pas un tel objet de collection, mais simplement l'objet Shop qui appartient à l'utilisateur - ou nul si l'utilisateur n'a pas encore de boutique. Puisque ni les objets Shop ni nil n'ont decreate
méthode, vous ne pouvez pas utilisercreate
cette méthode avec leshas_one
relations.la source
@user.create_shop(params[:shop])
. Voir les méthodes ajoutées par has_one .Une manière plus concise de le faire est de:
Voir les méthodes ajoutées par has_one dans les guides Ruby on Rails.
la source
@user.create_shop(params[:shop_one_info])
cela créera shop_one, MAIS si vous exécutez@user.create_shop(params[:shop_two_info])
cela, il supprimera le premier magasin et créera le second.@user.build_shop(params)
Deux autres façons si vous le souhaitez
save
au lieu decreate
:la source
Juste pour ajouter aux réponses ci-dessus -
La syntaxe ci-dessus crée un nouvel enregistrement, mais elle supprime ensuite l'enregistrement existant similaire.
Sinon, si vous ne souhaitez pas déclencher le rappel de suppression
Ce fil pourrait être utile. Cliquez ici
la source