J'ai une entité utilisateur qui a un champ de localisation actuel (ville et pays). Pour contenir ces informations, j'ai créé une entité appelée emplacement que HAS_MANY utilisateurs.
Je ne suis pas tout à fait sûr si je devrais mettre dans le modèle utilisateur "has_one" ou "appartient_to", mais pour ce que je lis si je voulais que cela ait La clé étrangère de l'emplacement que je devrais mettre "appartient à". Je souhaite également pouvoir modifier l'emplacement actuel de l'utilisateur lors de la modification de l'utilisateur. Donc, j'utilise des attributs imbriqués. Mais lorsque je modifie l'utilisateur, je finis par ajouter un nouvel emplacement à chaque fois sans jamais l'associer à l'utilisateur édité. Peux-tu m'aider? P>
Mon code est le suivant: P>
#User Model class User < ActiveRecord::Base ## Relationships belongs_to :current_location, :class_name => 'Location' accepts_nested_attributes_for :current_location end #Location Model class Location < ActiveRecord::Base #Relationship has_many :users end # part of the _form_edit.haml - form_edit.fields_for :current_location do |location_form| = location_form.label :location, "Current Location" = location_form.text_field :location #Application Helper #nested attributes for user and location def setup_user(user) returning(user) do |u| u.build_current_location if u.current_location.nil? end end #in the user controller (added after edit) def update @user = @current_user if @user.update_attributes(params[:user]) flash[:notice] = "Account updated!" redirect_to account_url else render :action => :edit end end
4 Réponses :
Vous ne fournissez pas l'ID de l'attribut imbriqué. Donc, les rails pensent que c'est un nouveau.
Salut. Merci pour votre réponse rapide. J'ai ajouté ce champ mais la même chose continue à arriver. Il ajoute un nouvel emplacement à la table. Et cela ne fait pas l'association pour l'utilisateur. Donc, le spectacle.haml ne montre jamais le courant_location :( c'est toujours vide.
Je ne sais pas si la réponse précédente est vraiment correcte. Ce dont vous avez besoin est de spécifier l'identifiant de l'utilisateur pour l'emplacement, pas l'emplacement lui-même.
Bonjour, merci pour votre réponse. Lorsque j'ajoute ce champ caché, je reçois le message d'erreur suivant: "Méthode non définie` user_id 'pour #
Oh, désolé, confondu quelque chose dans votre modèle de domaine. Vous devriez essayer form_edit.hidden_field: emplacement_id
Re-bonjour. essayé à nouveau le caché_field avec: emplacement_id et: actuel_location_id ... mais néanmoins, il continue de ne pas fonctionner comme il se doit = (
Le problème exact que vous rencontrez, car d'autres ont souligné que votre contrôleur ne reçoit pas l'identifiant de l'emplacement tel qu'il le devrait. Je tire à moi que l'identifiant de l'emplacement est transmis par le mauvais paramètre. Malheureusement, un identifiant d'emplacement n'existe pas sur un nouvel enregistrement, cela n'est donc pas possible dans le formulaire.
Votre problème provient de l'utilisation accepte_netés_attributes_for sur une relation appartient à une relation. Le comportement n'est pas clairement défini. Cela semble être un bug documenté. Donc, les accepts_netés_attributes_for doivent être sur un ou possède de nombreux aspects d'une relation. P>
Voici quelques solutions possibles: P>
déplacez le modèle accepté_nedesd_attributes_for vers le modèle d'emplacement et construisez vos formulaires l'inverse. P>
def update @user = @current_user completed = false location_params = params[:user].delete(:current_location_attributes) User.transaction do @location = Location.find_or_create_by_id(location_params) @user.update_attributes(params[:user]) @user.current_location = @location @user.save! completed = true end if completed flash[:notice] = "Account updated!" redirect_to account_url else render :action => :edit end end
Utilisez un modèle de jointure et faites-en un: par rapport à la relation. P>
Je ne sais honnêtement pas comment bien accepter_neté_attributes_for fonctionne avec une relation: par rapport, mais cela résoudra certainement votre problème avec des enregistrements de liaison. P> LI>
Ignorer accepte_ned_attributes_for et gérer l'association dans votre contrôleur à l'ancienne façon façonnée. P>
Conservez effectivement les accepts_ned_attributes_for. Il fournit des méthodes de commodité utiles, tout simplement ne le laissez pas arriver à la mise à jour_attributes / créer une déclaration. P>
-form_for @location do |location_form| ... =location_form.fields_for @user do |user_form| ....
salut emfi tks pour votre réponse. Je ne savais pas que c'était un bug connu ... mais j'ai vraiment essayé de rechercher une solution et je n'ai rien trouvé. Concernant les 3 options. 1- n'est en effet pas le meilleur, à cette fin .. = / parce que je veux changer l'emplacement d'un utilisateur. 2- Je ne sais pas comment faire cela pour dire la vérité ... 3- Cela semblait assez gentil et je l'ai essayé mais ça ne marche pas. = / Au début, il a dit qu'il n'y avait pas de "Supprimer!" fonction, mais après avoir retiré le "!" Cela n'avait aucune erreur. Cela n'associe tout simplement pas l'emplacement avec l'utilisateur: S Il en crée simplement et c'est tout ...: s des idées? : /
Oui, j'ai supposé qu'il y avait une suppression destructrice sur hachage. Aussi à ma hâte, j'ai oublié d'ajouter la ligne qui associe réellement l'utilisateur avec l'emplacement. J'ai corrigé l'erreur.
Je ne sais pas ce qui ne va pas, mais malheureusement, cela ne semble pas faire le tour :( désolé: s
Obtenez-vous des erreurs? Exactement quels paramètres sont la réception du contrôleur?
Pour ce que je vois, c'est l'envoi de cela: "actuel_location_attributes" => {"Lieu" => "Porto, Portugal"}, je ne sais pas si cela devrait avoir le: ID de l'emplacement ... Comment faire ça? Je n'ai aucune erreur maintenant.
On dirait que j'ai brillant sur un autre détail: mon code retirait l'emplacement_attributes, au lieu de courant_location_attributes à partir du hachage des params. Mis à jour pour l'exactitude.
Salut là-bas, je pense que dans le champ caché, il devrait être @ user.Currrent_location.new_record? droit? Sinon, je reçois une erreur pour une variable ou une méthode non existante avec le nom "Current_Location". Néanmoins, cela n'envoie toujours aucune pièce d'identité ni que cela ne fonctionne :( Je vais faire fou avec ceci. Si cela finit de ne pas fonctionner, je vais simplement déplacer l'actuel_location à l'utilisateur.: S
Par défaut appartiends_to: actuel_location,: class_name => 'Emplacement' code> s'attendre à ce que les utilisateurs code> code> ont un champ
actuel_location_id code>. Une fois que vous avez ceci, vous devriez être capable de faire quelque chose comme:
Et dans le contrôleur qui enregistre les données, qu'est-ce que vous avez?
J'ai: DEF Update @user = @Current_user if @ user.update_attributes (paramètres [: utilisateur]) flash [: Avis] = "compte mis à jour!" Redirect_to Compte_url sinon rendu: action =>: Modifier la fin de fin