Reputation: 73
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
Upvotes: 1
Views: 1865
Reputation: 1055
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,
Upvotes: 2