2016-07-20 29 views
0

Verwenden Sie auch Mongoid, wenn dies relevant ist.Fehler bei der Verwendung von FactoryGirl mit has_secure_password in der Featurespezifikation

Wenn ich einen Benutzer mit Factory-Girl erstellen, heißt es, der Benutzer ist gültig. Wenn ich jedoch über ActiveRecord auf diesen Benutzer zugreife, sagt es, dass es ungültig ist. Hier ist ein Überblick über das Thema:

user = create(:user, :activated) 
user.valid? # => true 
User.count # => 1 
db_user = User.first 
db_user == user # => true 
db_user.valid? # => false 
db_user.errors.count # => 0 
# it only shows the error messages once I try to modify an attribute 
db_user.email = "[email protected]" 
db_user.save # => false 
db_user.errors # => @messages={:password=>["is too short (minimum is 6 characters)", "can't be blank"]} 

Hier ist meine Fabrik:

FactoryGirl.define do 
    factory :user do 
    name { Faker::Name.name } 
    email { "#{name.gsub(/[^0-9a-zA-Z]/i, '')}@example.com" } 
    phone { Faker::Base.numerify("#{"#" * 10}") } 
    admin false 
    password "password" 
    password_confirmation "password" 
    end 
end 

Hier ist die relevanten Teile des User-Modell:

class User 
    include Mongoid::Document 
    include ActiveModel::SecurePassword 

    field :name,    type: String 
    field :email,    type: String 
    validates :password, length: { minimum: 6 }, 
         presence: true 
    has_secure_password 
+0

Update - Dieses Problem scheint mit meinem Problem in Verbindung zu stehen https://github.com/mongoid-rspec/mongoid-rspec/issues/135 –

Antwort

0

Es ist wichtig, zu verstehen, wie has_secure_password arbeitet intern: Wenn ein Benutzer erstellt oder das Passwort geändert werden soll, sein password (und ein password_confirmation) Attribut gesetzt werden muss. Aber intern wird das password Feld nicht in der Datenbank gespeichert, aber sein Wert wird Hash und in einem Datenbankfeld mit dem Namen password_digest gespeichert.

Das bedeutet: Wenn Sie einen vorhandenen Benutzer aus der Datenbank laden, ist sein password Attribut nil (aber password_digest wird vorhanden sein). Daher ist es nicht gültig, wenn Sie einen solchen Benutzer auf das Vorhandensein eines password überprüfen.

dieses Problem nur auf das Vorhandensein eines Passworts bestätigt Um zu vermeiden, wenn Sie einen neuen Benutzer erstellen oder wenn der Benutzer ein password hat, die nicht leer was bedeutet, der Benutzer versucht, das Kennwort zu aktualisieren:

# there must be a password on create 
validates :password, presence: true, on: :create 

# the password must follow conventions when present (of example on update) 
validates :password, length: { minimum: 6 }, allow_blank: true 
+0

Das löst es so ziemlich, danke! Eine Sache, die hinzugefügt werden muss, ist, dass die Standardvalidierung weiterhin erlaubt, dass leere Zeichenfolgen über ein Passwort zurückgesetzt werden, so dass es eine zusätzliche Validierung geben sollte, die überprüft, dass 'password.nil? || password.present? 'ist wahr –

0

Sie immer Ihre zusätzliche Validierung ausgeführt wird. has_secure_password überprüft bereits die password. Sie benötigen also keine Anwesenheitsvalidierung.

könnten Sie einfach Ihre Validierung abhängig machen

validates :password, length: { minimum: 6 }, if: Proc.new{|u| u.password_changed? } 

arbeiten sollte ich meinen ActiveModel mit :: Schmutzige

Wenn nicht, können Sie nur die Validierung ausgeführt werden, wenn es vorhanden ist.

validates :password, length: { minimum: 6 }, if: Proc.new{|u| u.password.present? } 
+0

Es funktioniert, wenn ich alle Passwortvalidierungen abziehe, aber es sieht nicht so aus, als ob es die Anwesenheit mehr validiert . –

+0

'user = build (: user, password:" ") .valid?' Gibt true zurück –

+0

Weird, sollte es nach den Rails api. Sie können die Anwesenheitsvalidierung immer wieder hinzufügen, wenn Sie nicht herausfinden können, warum sie nicht funktioniert. –

0

Ich beschloss, einen Blick auf die "Rails Tutorial - Adding a secure password" Abschnitt von Michael Hartl zu nehmen. Ich sah, dass er den Code mit has_secure_passwordvorvalidates schrieb, wie unten dargestellt:

has_secure_password 
validates :password, presence: true, length: { minimum: 6 } 

Versuchen Sie, die Reihenfolge zu ändern und sehen, ob das funktioniert. Ich habe es getestet, aber dies ist eine der wichtigsten Ressourcen, die ich verwendet habe, als ich anfing und es funktionierte für mich in der Vergangenheit. Viel Glück.

+0

Funktioniert nicht, auch nach der Änderung der Reihenfolge. Ich glaube, ich habe ein ungelöstes GitHub-Problem zu dem Problem gefunden, das ich dem Beitrag hinzugefügt habe. –

+0

@ ben-muschol können Sie bitte einen Link zum Github-Problem hinzufügen, falls andere Benutzer das gleiche Problem haben? Vielen Dank. –

+0

Es ist in einem Kommentar auf den Beitrag, hier ist der Link: https://github.com/mongoid-rspec/mongoid-rspec/issues/135 –