2017-06-22 3 views
0

Dites que j'ai deux tables, trees et apples et une table jointe tree_apples. Supposons que la table tree_apples comporte deux colonnes importantes appelées rotten (booléenne) et branch (int).Rails update_nested_attributes. HOw met-il à jour s'il existe, crée si ce n'est pas le cas?

Say dans le contrôleur pour trees, j'ai ceci:

@tree.update_nested_attributes(tree_params) et ma méthode tree_params ressembler à ceci:

tree_apple_params: { 
    :apple_id, 
    :rotten, 
    :branch 
} 

Dis l'arbre que je mise à jour a déjà un tree_apple avec un id de 3 c'est rotten: true et branches: nil et les paramètres entrant dans ce contrôleur pour mettre à jour la branche a des paramètres qui ressemblent à ceci:

tree_apple_params: [{ 
    apple_id: 3, 
    rotten: nil, 
    branch: 5 
    }, 
    { 
    apple_id: 4, 
    rotten: nil, 
    branch: 6 
    }, 
    ... 
] 

Il est donc params de créer ou de mettre à jour un groupe de tree_apples. La page à partir de laquelle les paramètres viennent de mettre à jour la branche pour tree_apple qui fait référence à apple_id de 3, et pour cela tree_apple il ne fournit aucune entrée sur l'état pourri. Je ne veux pas créer un autre tree_apple qui référence apple_id: 3 qui a nil pour l'état rotten. Je veux mettre à jour le tree_apple existant. Donc, pour ce tree_apple, je voudrais le trouver, puis mettre à jour avec la branche 5. Mais pour tous les autres params qui référencent des pommes qui n'existent pas sur cet arbre, je voudrais créer nouveau tree_apples si le tree_apple n'existe pas.

Existe-t-il un moyen de le faire? Cette logique appartient-elle au contrôleur ou au modèle en tant que rappel?

Répondre

0

Regardez dans find_or_create_by

Quelque chose le long des lignes de:

tree_params.each do |params| 
    tree_apple = TreeApple.find_or_create_by(apple_id: params[:apple_id]) 
    tree_apple.update_attributes(branch: params[:branch], rotten: params[:rotten]) 
end 

dans votre contrôleur.

+0

@jwan ne que résoudre votre problème? – George

0

Vous devez transmettre l'ID de l'enregistrement tree_apple si vous souhaitez le mettre à jour, par ex.

tree_apple_params: [{ 
id: 1, #passing the id of the tree_apple record here will update existing records 
apple_id: 3, 
rotten: nil, 
branch: 5 
}, 
{ #passing NO id here will create records 
apple_id: 4, 
rotten: nil, 
branch: 6 
}, 
... 
] 

Et permettent évidemment l'id dans votre params:

tree_apple_params: { 
    :id, 
    :apple_id, 
    :rotten, 
    :branch 
} 
+0

Pouvez-vous mettre à jour 'tree_apples' avec n'importe quel attribut autre que id? Pouvez-vous dire à rails de mettre à jour tant que 'apple_id' est le même à la place? – Jwan622

+0

Si vous ne transmettez pas l'ID, vous devez trouver l'enregistrement pour le mettre à jour comme @George l'a suggéré dans sa réponse –