简体   繁体   中英

Rails Error Message: ActiveRecord::NotNullViolation

Hello I am receiving the following error:
ActiveRecord::NotNullViolation
I've checked the rails main page and it seems this error is caused when a record cannot be inserted or updated because it would violate a not null constraint.
My question is how do I bypass this error? Ideally, I would like to store the user session data but I am not sure of how to fix this.

Note: I am using Devise and Omni-Auth: Twitter

Here is the 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

Here is the full error message:

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

I think the broblem came from inside "from_omniauth" method.

Twitter does NOT give you an email via API

So when you first_or_create the user with a null email from "auth.info.email" it will raise exception.

Because your User's email column is:

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

Hope this help,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM