2017-09-29 6 views
0

Bonjour Je reçois l'erreur suivante:
ActiveRecord::NotNullViolation
J'ai vérifié les rails page principale et il semble que cette erreur est due lorsqu'un enregistrement ne peut pas être inséré ou mis à jour, car elle violer une contrainte non nulle.
Ma question est comment puis-je contourner cette erreur? Idéalement, je voudrais stocker les données de session de l'utilisateur, mais je ne suis pas sûr de savoir comment résoudre ce problème.Rails Message d'erreur: ActiveRecord :: NotNullViolation

Note: J'utilise Devise et Omni-Auth: Twitter

Voici le schema.rb

ActiveRecord::Schema.define(version: 20170928215550) do 
create_table "users", force: :cascade do |t| 
    t.string "email", default: "", null: false 
    t.string "encrypted_password", default: "", null: false 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count", default: 0, null: false 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.string "current_sign_in_ip" 
    t.string "last_sign_in_ip" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.string "provider" 
    t.string "uid" 
    t.index ["email"], name: "index_users_on_email", unique: true 
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true 
end 
end 

App > Models > user.rb

class User < ApplicationRecord 
# Include default devise modules. Others available are: 
# :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:twitter] 
    # method to handle data response from twitter 
    def self.from_omniauth(auth) 
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| 
    user.provider = auth.provider 
    user.uid = auth.uid 
    user.email = auth.info.email 
    user.password = Devise.friendly_token[0, 20] 
    end 
end 
end 

App > Controllers > users > omniauth_callbacks_controller.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController 
    def twitter 
    @user = User.from_omniauth(request.env["omniauth.auth"]) 
    sign_in_and_redirect @user 
    set_flash_message(:notice, :success, :kind => "Twitter") 
    end 
    def failure 
    redirect_to 'home' 
    end 
end 

Voici le message d'erreur complet:

SQLite3::ConstraintException: NOT NULL constraint failed: users.email: INSERT INTO "users" ("email", "encrypted_password", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "current_sign_in_ip", "last_sign_in_ip", "created_at", "updated_at", "provider", "uid") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 

Extracted source (around line #4): 

def twitter 
    @user = User.from_omniauth(request.env["omniauth.auth"]) 
    LINE 4--> sign_in_and_redirect @user 
    set_flash_message(:notice, :success, :kind => "Twitter") 
end 
def failure 
+0

Afficher la sortie du journal quant à la demande. –

Répondre

2

Je pense que le broblem est venu de méthode "from_omniauth" à l'intérieur.

Twitter ne vous donne pas un email via l'API

Ainsi, lorsque vous first_or_create à l'utilisateur un email nul de « auth.info.email » résultat est une exception.

Parce que votre colonne e-mail de l'utilisateur est:

t.string "email", default: "", null: false 

espoir cette aide,

+0

Huynh Cela a résolu le problème! J'ai dû mettre à jour le schéma de sorte que j'avais une colonne pour le nom au lieu d'un email. Comme vous l'avez mentionné, la réponse Twitter n'inclut pas d'e-mail, j'ai donc choisi de stocker le nom de l'utilisateur à la place. Merci encore! –