2010-02-16 5 views
19

Ich habe ein Benutzermodell, das ein E-Mail- und ein Passwort-Feld hat. Aus Sicherheitsgründen können diese nicht gleich sein. Wie kann ich das in meinem Modell definieren?Wie validiere ich, dass zwei Werte in einem Rails-Modell nicht gleich sind?

+0

Das ist seltsam, warum später Antwort akzeptiert wurde, während andere fast gleich sind? –

+0

@Dejw es ist die kürzeste, die funktioniert nicht nur erstellen –

+0

Vielen Dank für die Erklärung.Nichtsdestoweniger war klews Antwort kürzer ;-) –

Antwort

23

Create custom validataion:

validate :check_email_and_password 

def check_email_and_password 
    errors.add(:password, "can't be the same as email") if email == password 
end 

Aber denken Sie daran, dass das Kennwort als Klartext zu speichern ist keine gute Idee. Sie sollten es hashed speichern. Versuchen Sie einige Authentifizierungs-Plugins wie authlogic oder Restful authentication.

6

Sie können eine benutzerdefinierte Überprüfungsmethode verwenden, um dies zu überprüfen.

class User < ActiveRecord::Base 
    # ... 

    def validate 
    if (self.email == self.password) 
     errors.add(:password, "password cannot equal email") 
     errors.add(:email, "email cannot equal password") 
    end 
    end 
end 
1

alles, was Sie brauchen, ist Gültigkeitsregel in Ihrem Modell zum Beispiel

class User < ActiveRecord::Base 
    def validate_on_create 
    if email == password 
     errors.add("password", "email and password can't be the same") 
    end 
    end 
end 
+1

Ich glaube nicht, dass das richtig ist. Wir wollen 'validate', nicht' validate_on_create', weil wir alle Saves überprüfen müssen, dass die E-Mail nicht das Passwort ist (nicht nur zum Zeitpunkt der Erstellung). –

+0

Es gibt einen Syntaxfehler (Tippfehler) in der Fehlermeldung: Sie können keine Anführungszeichen in Strings verwenden, die einfach zitiert werden ;-) –

4

Es hängt davon ab, wie Ihr Passwort gespeichert zu erstellen ist:

class User < ActiveRecord::Base 
    validate :email_and_password_validation 

    def email_and_password_validation 
     if self.email == self.password 
      errors.add_to_base("Password must be different from email") 
     end 
    end 
end 

Dies würde funktionieren, wenn Ihr Passwort ist wörtlich gespeichert, aber Sie können die gleiche Sache mit E-Mail (z. B. erstellen Sie eine Hash-Version) und prüfen Sie auf Gleichheit mit Passwort. Z. B:

class User < ActiveRecord::Base 
    validate :email_and_password_validation 

    def email_and_password_validation 
     if make_hash(self.email) == self.hashed_password 
      errors.add_to_base("Password must be different from email") 
     end 
    end 
end 

Mein Beispiel von http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002162

Ihre Situation genommen wird, ist ganz allgemein so Sie interessiert sein können benutzerdefinierte Validierungsverfahren zu schaffen. Alles wird hier abgedeckt: http://guides.rubyonrails.org/active_record_validations_callbacks.html#creating-custom-validation-methods

+0

Letzter Link gibt 404 – Rekin

+0

Fester Link (aus alter Version von Rails Guides). Vielen Dank. –

4

es ist viel klüger benutzerdefinierten Validator zu verwenden, hier ist der Code für den universellen Validator, die

class ValuesNotEqualValidator < ActiveModel::Validator 
    def validate(record) 
    if options[:fields].any? && options[:fields].size >= 2 
     field_values = options[:fields].collect { |f| record.send(f) } 
     unless field_values.size == field_values.uniq.size 
     record.errors[:base] << 
      (options[:msg].blank? ? "fields: #{options[:fields].join(", ")} - should not be equal" : 
       options[:msg]) 
     end 
    else 
     raise "#{self.class.name} require at least two fields as options [e.g. fields: [:giver_id, :receiver_id]" 
    end 
    end 
end 

verwendet werden kann und es dann gerne verwenden:

class User < ActiveRecord::Base 
    # ... 
    validates_with ValuesNotEqualValidator, fields: [:email, :password], msg: "This Person is evil" 
end 
0

Wenn Sie mehrere Sprachen unterstützen möchten müssen Sie eine andere Lösung finden, die die Fehlermeldungen und die Attributnamen übersetzt. Also habe ich für jeden einen Validator erstellt.

validators/values_not_equal_validator.rb:
class ValuesNotEqualValidator < ActiveModel::EachValidator 
    def validate(record) 
    @past = Hash.new 
    super 
    end 

    def validate_each(record, attribute, value) 
    @past.each do |k, v| 
     if v == value 
     record.errors.add(attribute, I18n.t('errors.messages.should_not_be_equal_to') + " " + record.class.human_attribute_name(k)) 
     end 
    end 
    @past[attribute] = value 
    end 
end 

Ich nenne es im Modell wie folgt aus:

class User < ActiveRecord::Base 
    validates :forename, :surname, values_not_equal: true 
end 

Und ich es die Nachrichten wie folgt übersetzen:

de: 
    activerecord: 
    attributes: 
     user: 
     forename: 'Vorname' 
     surname: 'Nachname' 
    errors: 
    messages: 
     should_not_be_equal_to: 'darf nicht gleich sein wie' 
4

Neuer Weg:

validates :password, exclusion: { in: lambda{ |user| [user.email] } } 

oder:

validates :password, exclusion: { in: ->(user) { [user.email] } } 
+0

Bitte klären Sie, was Sie mit "neuer Weg" meinen. Welcher Rubin/Rails ist das? – oklas

+0

Es funktionierte zumindest von Rails 3.2.22/Ruby 2.2.6 - ausgezeichnete kurze Lösung. Vielen Dank. – oklas

Verwandte Themen