2010-01-27 7 views
8

Ich wollte benutzerdefinierte Fehlermeldungen für meine Feldnamen haben. Ich stolperte über ein anderes SO questionbenutzerdefinierte Fehlermeldung für gültige Anzahl von in Schienen

So habe ich so etwas wie dieses:

class Product < ActiveRecord::Base 
    validate do |prod| 
    prod.errors.add_to_base("Product price can't be blank") if prod.prod_price.blank? 
    end 
end 

Aber ich möchte auch die numericality von prod_price überprüfen. Wenn ich nur validate_numericality_of :prod_price hinzufügen und der Produktpreis leer ist, werden beide Fehlermeldungen angezeigt (leer und keine Nummer).

Wie kann ich nur 'ist keine Nummer' Fehlermeldung nur angezeigt, wenn der Produktpreis nicht leer ist?

Ich versuchte

class Product < ActiveRecord::Base 
    validate do |prod| 
    prod.errors.add_to_base("Product price can't be blank") if prod.prod_price.blank? 
    if !prod.prod_price.blank? 
     prod.errors.add_to_base("Product price must be a number") if prod.prod_price.<whatdo i put here> 
    end 
    end 
end 

auch tun, Wie kann ich eine benutzerdefinierte Nachricht für haben ‚keine Zahl‘. Ich möchte den Namen meiner Spalte dem Benutzer anzeigen.

Antwort

5

Sie können benutzerdefinierte Nachrichten haben, ohne Ihre eigene Validierungsmethode zu schreiben. Nur :message hinzufügen:

validates_presence_of :prod_price, :message => "Product price can't be blank"

Wenn Sie die numericality Validierung überspringen möchten, wenn prod_price nicht vorhanden ist, fügen: allow_nil:

validates_presence_of :prod_price, :message => "Product price can't be blank" validates_numericality_of :prod_price, :allow_nil => true

Dann wird die numericality Prüfung wird nicht ausgeführt, wenn prod_price fehlt.

EDIT:

Warten Sie nicht der Feldname in der Fehlermeldung zeigen wollen, nicht wahr? Das habe ich vermisst. Sie benötigen also die benutzerdefinierte Validierung.

EDIT # 2:

Ok, wie etwa diese dann:

protected 

def validate 
    if prod_price.blank? 
    errors.add "Product price can't be blank" 
    else 
    begin 
     Integer(attributes_before_type_cast["prod_price"]) 
    rescue ArgumentError 
     errors.add "Product price must be a number" 
    end 
    end 
end 
+0

yeah ... sollte meine Spaltennamen besser benannt haben, um all diese Unordnung zu vermeiden – Omnipresent

1

Für viele Gründe, es sei denn, Sie etwas Ungewöhnliches tun müssen, sollten Sie Fehlermeldungen auf bestimmte Felder werden angebracht (es ist einfacher zu Unit-Tests zu tun, leichter zu später Fehler zu ändern, können Sie Marker neben ungültige Felder anzeigen, wenn Sie wollen, etc). Ich denke, was Sie tun möchten, kann mit diesem erreicht werden:

class Product < ActiveRecord::Base 
    validates_numericality_of :name, :if => lambda{ |obj| obj.prod_price? } 
    validates_presence_of :name 
end 
+0

, aber dies wird den Feldnamen in der Fehlermeldung zeigen. Ich möchte mich davon entfernen. Wie kann Ihr Code mit den benutzerdefinierten Nachrichten integriert werden Ich habe – Omnipresent

+0

Ich ermutige Sie zu prüfen, wie Rails Feldfehlermeldungen (möglicherweise eine andere Frage, wie der humanisierte Feldname zu AR Fehlermeldungen nicht vorangestellt werden). Das Hinzufügen aller Fehler zur Basis ist kein großartiges Design. Ersetzen Sie nicht den Motor Ihres Autos, weil Sie die Farbe nicht mögen! –

0

ich von den anderen, diesen Ansatz nahm SO

class User < ActiveRecord::Base 

    HUMANIZED_ATTRIBUTES = { 
    :email => "E-mail address" 
    } 

    def self.human_attribute_name(attr) 
    HUMANIZED_ATTRIBUTES[attr.to_sym] || super 
    end 

end 

diese Weise, die ich schreiben müssen, um benutzerdefinierte Nachricht für jedes Feld nicht in Frage stellen. Ich ändern Sie einfach den fild Namen dem Benutzer präsentiert

+0

Hey, das ist viel besser! – zetetic

0
if prod.prod_price.blank? 
    prod.errors.add_to_base("Product price can't be blank") 
elsif prod.prod_price.match(/[^\d]/) 
    prod.errors.add_to_base("Product price must be a number") 
end 
3

Die currently accepted answer funktioniert, aber hier ist eine datengesteuerte Art und Weise es mit Rails' i18n zu tun:

allow_blank: true-validates_numericality_of Das Hinzufügen des leeren Problem kümmern .

Dann können Sie i18n verwenden, um Attributnamen automatisch für Sie zu übersetzen (Dok. here). Für prod_price würden Sie nur fügen Sie diese en.yml:

en: 
    activerecord: 
    attributes: 
     product: 
     prod_price: "Product price" 

Jetzt für die eine Reihe Teil sein müssen, wir i18n wieder verwenden können. Von the docs:

Active Record Validierung Fehlermeldungen können auch leicht übersetzt werden. Active Record bietet Ihnen eine Reihe von Namespaces, in denen Sie Ihre Nachrichtenübersetzungen platzieren können, um verschiedene Nachrichten und Übersetzungen für bestimmte Modelle, Attribute und/oder Validierungen bereitzustellen.

Es gibt eine praktische Tabelle dieser Namespaces here, wo Sie, dass die Nachricht für eine numericality validataion not_a_number ist zu sehen.

So, jetzt können wir das en.yml so hinzufügen:

en: 
    activerecord: 
    errors: 
     models: 
     product: 
      attributes: 
      prod_price: 
       not_a_number: "must be a number" 

Nun, wenn die Validierung fehlschlägt er die beiden verketten werden, Sie geben: Produktpreis eine Reihe sein muss.

Verwandte Themen