I recently migrated from Rails 6.1 to 7.0 and I keep getting the error when I try to sign up a user.
NameError (undefined local variable or method `attributes' for nil:NilClass
Did you mean? attribute_names):
activemodel (7.0.2.2) lib/active_model/serialization.rb:153:in `attribute_names'
actionpack (7.0.2.2) lib/action_controller/metal/params_wrapper.rb:118:in `block in include'
/Users/axel/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/mutex_m.rb:78:in `synchronize'
/Users/axel/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/mutex_m.rb:78:in `mu_synchronize'
actionpack (7.0.2.2) lib/action_controller/metal/params_wrapper.rb:112:in `include'
actionpack (7.0.2.2) lib/action_controller/metal/params_wrapper.rb:278:in `_extract_parameters'
Something tells me I need to implement some attribute
in the User model maybe because I have validation for email
. I have tried
include ActiveModel::Serialization
attr_accessor :email
def attributes
{'email' => nil}
end
But nothing works.
Here is my User model
require 'druuid'
class User < ApplicationRecord
before_create :downcase_email
before_update :downcase_email
# No confirmations or password resets in Development
if Rails.env.production?
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :validatable, :lockable,
:omniauthable, omniauth_providers: [:google_oauth2],
authentication_keys: [:email]
else
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable,
:omniauthable, omniauth_providers: [:google_oauth2],
authentication_keys: [:email]
end
# ------------- validations -------------
validates :email,
presence: { message: "can't be empty"},
:uniqueness => {:case_sensitive => false}
def downcase_email
self.email = self.email.downcase
end
# ------------- Omniauth -------------
# Check Omniauth Controller
def self.from_omniauth(auth)
user = User.where(email: auth.info.email).first
if user
# record.update() returns a boolean value, user is automatically updated
user.update(refresh_token: auth.credentials.refresh_token,
access_token: auth.credentials.token,
provider_uid: auth.uid,
provider: auth.provider,
)
else
user = User.create(email: auth.info.email,
provider_uid: auth.uid,
provider: auth.provider,
refresh_token: auth.credentials.refresh_token,
access_token: auth.credentials.token,
password: Devise.friendly_token[0, 20],
firstname: auth.info.first_name,
lastname: auth.info.last_name,
)
end
user
end
end
Here is my serializer with ActiveModelSerializers
class UserSerializer < ActiveModel::Serializer
# Basic
attributes :id, :email, :uid, :firstname, :lastname
end
You need to include Active Model Serialization wherever you're initializing the serializer.
For instance, in your /application_controller.rb
:
class ApplicationController < ActionController::API
include ActiveModel::Serialization
end