2012-04-05 5 views
1

DataMapper-Modelle ermöglichen benutzerdefinierte Validierungen von zwei Formen: die für eine Eigenschaft spezifischen und Gesamtvalidierungen von Objekten. Zum Beispiel:Wie kann ich DataMapper-Fehler auflisten, die nicht an eine Eigenschaft gebunden sind?

# Validates the `name` property with the `check_name` method; 
# any errors will be under `object.errors[:name]` 
validates_with_method :name, method: :check_name 

# Validates the object overall with the `overall_soundness` method; 
# any errors will be under `object.errors[:overall_soundness]` 
validates_with_method :overall_soundness 

Die zweite Art Sinn für Validierungen macht, die mehrere Eigenschaften beinhalten, aber es stellt auch ein Problem: Fehler für den Benutzer.

Ich möchte alle Fehler anzeigen, die nicht an eine bestimmte Eigenschaft an der Spitze der Formularseite angehängt sind, aber ich sehe keine einfache Möglichkeit, sie aufzulisten.

Wie kann ich eine Liste von nicht eigenschaftsspezifischen Fehlern erhalten?

(Ich verwende DataMapper 1.2.0)

Antwort

0

A hacky Weg

Ich hoffe, dies gibt es eine einheimische Art und Weise als. Ich habe diese Methode, um mein Modell hinzugefügt:

# Validation errors not tied to a specific property. For instance, 
# "end date must be on or before start date" (neither property is 
# wrong individually, but the combination makes the model invalid) 
# @return [Array] of error message strings 
def general_validation_errors 
    general_errors = [] 

    general_error_keys = errors.keys.reject do |error| 
    # Throw away any errors that match property names 
    self.send(:properties).map(&:name).include?(error) || error == :error 
    end 

    general_error_keys.each do |key| 
    general_errors << self.errors[key] 
    end 

    general_errors.flatten 
end 

An der Spitze einer Form, kann ich dies tun:

- if @my_model.general_validation_errors.any? 
    .errors 
    %ul 
     - @my_model.general_validation_errors.each do |error_message| 
     %li= error_message 

Oder ein Affe Patch Formtastic f.general_validation_errors zu ermöglichen wäre:

# Let Formtastic forms use f.general_validation_errors to display these (if any) 
module Formtastic 
    module Helpers 
    module ErrorsHelper 
     def general_validation_errors 
     unless @object.respond_to?(:general_validation_errors) 
      raise ArgumentError.new(
      "#{@object.class} doesn't have a general_validation_errors method for Formtastic to call (did you include the module?)" 
     ) 
     end 

     if @object.general_validation_errors.any? 
      template.content_tag(:div, class: 'errors') do 
      template.content_tag(:ul) do 
       content = '' 
       @object.general_validation_errors.each do |error| 
       content << template.content_tag(:li) do 
        error 
       end 
       end 
       content.html_safe 
      end 
      end 
     end 
     end 
    end 
    end 
end 
+0

Oder Sie könnten nur mit Namen, wie 'special_overall_soundness' Ihre speziellen Fehler holen. Die Dokumentation für "validates_with_method" ermutigt Sie, sie mit jeweils einer Eigenschaft/Methode zu verwenden. – ujifgc

+0

Oder, wenn Sie Ihre Code-Unterbrechung auf DataMapper 1.3 möchten, könnten Sie Fehler von 'Model.validators.contexts auswählen [: default] .select {| k | k.kind_of? DataMapper :: Validations :: MethodValidator} ' – ujifgc

+0

@ujifgc - Ich bin ** erklären ** die Validierungen einzeln, aber ich möchte sie alle an einem Ort für den Benutzer auflisten. Ich listet bereits feldspezifische Fehler neben dem Formularfeld auf. Ich möchte diese anderen alle in einer Liste an der Spitze. Außerdem: 'Model.validators.context [: default] .select {| k | k.kind_of? (DataMapper :: Validations :: MethodValidator} 'gibt alle Validierungen zurück und unterscheidet nicht zwischen feldspezifischen und anderen. Sie haben jeweils eine 'field_name'-Eigenschaft, aber' allgemeine 'Validierungen haben keine Null; haben ihren eigenen Namen, das hilft mir nicht. –

0

Für die Anzeige ... könnten Sie Flash verwenden?

Da Sie keine Sprache markiert haben, werde ich nur die Ruby und Sinatra-Sachen und vielleicht finden Sie das DSL-Äquivalent.

flash.now[:errors] Ihrer Ansicht nach mit den entsprechenden bedingten Anweisungen

und in Route flash[:errors] = User.errors

Verwandte Themen