2010-09-17 6 views
3

Je suis au courant des méthodes d'indicateur de base sales pour les rails, qui fonctionnent si les attributs directs d'un objet ont changé, je me demande comment déterminer si mes enfants ont été mis à jour ..Les rails déterminent si les objets de accept_nested_attributes_for objets ont changé?

J'ai un formulaire pour une collection de fichiers, nous l'appellerons un dossier . Un dossier accepte_nested_attributes_for: fichiers. Qu'est-ce que j'ai besoin de déterminer (dans l'action du contrôleur) est de savoir si les fichiers qui sont dans le hachage params sont différents de ceux qui sont dans la db .. Donc, l'utilisateur a supprimé l'un des fichiers, ont-ils ajouter un nouveau fichier, ou deux (supprimer un fichier, et ajouter un autre)

je dois déterminer parce que je dois rediriger l'utilisateur vers une autre action si elles supprimé un fichier, par rapport à l'ajout d'un nouveau fichier, par rapport aux attributs mis à jour du dossier.

Répondre

3
def update 
    @folder = Folder.find(params[:id]) 
    @folder.attributes = params[:folder] 

    add_new_file = false 
    delete_file = false 
    @folder.files.each do |file| 
    add_new_file = true if file.new_record? 
    delete_file = true if file.marked_for_destruction? 
    end 

    both = add_new_file && delete_file 

    if both 
    redirect_to "both_action" 
    elsif add_new_file 
    redirect_to "add_new_file_action" 
    elsif delete_file 
    redirect_to "delete_file_action" 
    else 
    redirect_to "folder_not_changed_action" 
    end 
end 

Parfois, vous voulez savoir que le dossier est modifié sans déterminer comment. Dans ce cas, vous pouvez utiliser le mode autosave dans votre association:

class Folder < ActiveRecord::Base 
    has_many :files, :autosave => true 
    accepts_nested_attributes_for :files 
    attr_accessible :files_attributes 
end 

Ensuite, dans le contrôleur, vous pouvez utiliser @folder.changed_for_autosave? qui retourne si oui ou non ce dossier a été modifié de quelque façon (? New_record ?, marked_for_destruction ?, changé), y compris si l'une de ses associations autosave imbriquées est également modifiée.

Mis à jour.

Vous pouvez déplacer la logique spécifique d'un modèle du contrôleur vers une méthode dans le modèle folder, par ex. @folder.how_changed?, qui peut renvoyer l'un de: add_new_file,: delete_file et les symboles etc. (je suis d'accord avec vous pour dire que c'est une meilleure pratique, j'aurais juste essayé de garder les choses simples). Ensuite, dans le contrôleur, vous pouvez garder la logique assez simple.

case @folder.how_changed? 
    when :both 
    redirect_to "both_action" 
    when :add_new_file 
    redirect_to "add_new_file_action" 
    when :delete_file 
    redirect_to "delete_file_action" 
    else 
    redirect_to "folder_not_changed_action" 
end 

Cette solution utilise 2 méthodes: new_record? et marked_for_destruction? sur chaque modèle enfant, parce que Rails in-box méthode changed_for_autosave? peut dire seulement que les enfants ont été changés sans façon. C'est juste la façon d'utiliser ces indicateurs pour atteindre votre objectif.

+0

Je ne suis pas un fan de faire beaucoup de logique dans le contrôleur, cela semble être une façon très ronde de faire les choses, je pensais qu'il y aurait moyen d'utiliser les indicateurs sales que les rails fournit. – Rabbott

+0

J'ai mis à jour la réponse. – Voldy

Questions connexes