2017-10-25 3 views
0

Ich habe versucht, dies zu erforschen, aber seltsamerweise scheint niemand dieses Problem zu haben, oder ich suche nicht richtig. Wie auch immer, hier ist mein user.rb. Ich kann einen Benutzer kein Problem erstellen und mein benutzerdefiniertes Feld, 'pin, wird gesetzt. Ich kann das 'Pin'-Feld aktualisieren. Wenn Sie jedoch versuchen, den Namen, die E-Mail-Adresse oder das Passwort zu ändern, schlagen sie fehl, da die PIN in der Validierung meines Modells leer ist. Wie überspringe ich die Pin-Validierung, wenn ich sie nicht aktualisiere? Wenn ich meine E-Mail aktualisiere, sendet sie immer noch eine Bestätigung, aber wenn ich auf den Link klicke, wird der Pin erneut bestätigt und die Bestätigung schlägt fehl. Außerdem möchte ich den Hash im Helfer nach_validation nicht neu generieren.Überspringen Validierung für benutzerdefinierte Felder hinzugefügt zu Devise-Benutzermodell

class User < ApplicationRecord 
    has_many :profiles, dependent: :destroy 
    has_many :general_settings, dependent: :destroy 
    has_many :profile_settings, through: :profiles 
    has_many :tags, dependent: :destroy 
    has_many :videos, through: :profiles 
    belongs_to :account_type 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable, 
     :confirmable 
    after_validation :create_parent_digest 
    validates :pin, presence: true, length:{ is: 4 }, confirmation: true 

    attr_accessor :pin, :pin_confirmation 

    def valid_pin?(pin) 
    Devise::Encryptor.compare(self.class, parent_digest, pin) 
    end 

private 

    def create_parent_digest 
     self.parent_digest = Devise::Encryptor.digest(self.class, pin) 
    end 
end 

Antwort

0

Nach dem Rails Guide können Sie Validierungen sparen überspringen durch Zugabe von `validate: false als auf Option. Zum Beispiel:

@user.save(validate: false) 
0
  1. sollten Sie Option on:http://guides.rubyonrails.org/active_record_validations.html#on

Zum Beispiel verwenden: validates :pin, presence: true, length:{ is: 4 }, confirmation: true, on: :create

oder Sie können einen benutzerdefinierten Rahmen für die Validierung

# in model 
validates :pin, presence: true, length:{ is: 4 }, confirmation: true, on: :validate_pin 

# in controller 
@user.save(context: :validate_pin) 
  1. Ich empfehle etwas nicht Rückrufe verwenden für das Erstellen, machen create_parent_digest nur eine öffentliche Methode und nennen es von Hand in Controller (oder Dienstobjekt)

    # UsersController 
    if @user.save 
        @user.create_parent_digest 
        ... 
    end 
    

bearbeiten: Sie können wie zu tun dies

# in model 
validates :pin, presence: true, length:{ is: 4 }, confirmation: true, on: :validate_pin 

# in controller 
def create 
    @user = User.new params 
    if @user.valid?(:validate_pin) 
    @user.create_parent_digest 
    @user.save 
    else 
    # do something like render :new 
    end 
end 
+0

Vielen Dank für Ihre Antwort. Das wird funktionieren, außer es wird den Pin nicht validieren, wenn ich es ändere. Irgendwie muss ich Devise sagen, die Validierung zu umgehen, wenn die Bestätigungsfelder für Pin und Pin auf der Bearbeitungsseite leer sind. Ich bemerke, dass Sie benutzerdefinierte Kontexte erstellen können, aber sie müssen an gültige übergeben werden? und nicht_valid? ausdrücklich. –

+0

Was den Callback betrifft, wie verhindere ich in diesem Fall, dass ein blanker Pin gespeichert wird, da der Devise-Controller den Datensatz speichert, bevor der Pin gehackt wird? –

+0

Ich denke, ich muss vielleicht eine benutzerdefinierte Validierungsmethode erstellen, die all die Dinge tut, die rails für mich tun und die Validierung beenden, wenn die Pin/Pin-Bestätigung leer ist und es einen Pin-Digest gibt, dann fügen Sie keine Fehler hinzu. –

Verwandte Themen