Question

Je cherche une variante de la méthode #save qui ne fera que sauvegarder attributs qui ne sont pas associés à des erreurs. Ainsi, un modèle peut être mis à jour sans être valide dans son ensemble, ce qui empêche toujours l'enregistrement de données non valides dans la base de données.

Par "attributs valides", j'entends les attributs qui donnent nil lors de l'appel de @ model_instance.errors.on (: attribut)

Quelqu'un a-t-il une idée de la manière de procéder?

Jusqu'à présent, j'ai les informations suivantes:

def save_valid_attributes 
 valid? 
 update_atrtibutes attributes.inject({}){|k, v, m| m[k] = v unless errors_on(k.to_sym); m} 
end 

Cela fonctionne s'il n'y a pas de traitement effectué sur l'affectation, ce qui est le cas dans mon cas. Par exemple, j'ai une colonne de base de données "start_date", et deux méthodes définies:

def nice_start_date=(startdate)
 self.start_date = Chronic.parse(startdate) || startdate
end

def nice_start_date
 self.start_date.to_s
end

Ces deux méthodes me permettent d'analyser correctement les dates saisies par l'utilisateur à l'aide de Chronic avant de sauvegarder. Donc, deuxième manière de faire ceci, un attribut à la fois:

def save_valid_attributes(attrib) 
  valid?
  attrib.each{|(k,v)| send("${k}=", v); save; reload)
end

Le modèle doit être rechargé à chaque fois car, si l'une des dates est invalide et n'enregistre pas, cela empêchera l'enregistrement de tous les autres attributs.

Y a-t-il une meilleure façon de faire cela? Je suis sûr que ce n'est pas un problème rare dans le monde Rails, je n'arrive pas à trouver quoi que ce soit dans l'univers des connaissances de Google.

Était-ce utile?

La solution

Je ne suis pas sûr de la chance que vous aurez avec cela sans beaucoup de déconner.

Peu importe la façon dont DRY et OO et votre infrastructure facilitent les choses (ce qui est dans ce cas - beaucoup =), vous devez toujours vous rappeler qu'elle s'exécute devant une base de données relationnelle standard, qui comporte des commits atomiques. définit les fonctionnalités . Il est conçu dès le départ pour vous assurer que toutes vos modifications sont validées ou aucune.

Vous allez effectivement utiliser cette fonctionnalité standard avec une fonctionnalité allant à 100% à l’encontre de la façon dont rails + a été conçu pour fonctionner. Ceci est susceptible de conduire (comme déjà dit) à des données incohérentes.

Cela dit. . . c'est toujours possible. Je regarderais dans les lignes de la validation manuelle des attributs qui vous intéressent, puis de la méthode intégrée object.update_attribute_with_validation_skipping.

Bonne chance!

Autres conseils

Vous pouvez écraser #save comme ceci:

def save
  errors.each do |attr, msg|
    send("#{attr}=", send("#{attr}_was"))
  end
  super
end

Ceci réinitialisera tous les attributs avec des erreurs attachées à leur valeur d'origine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top