Active Record:NameError(nil 的未定义局部变量或方法“属性”:NilClass 您是说吗?attribute_names)

发布于 2025-01-12 11:00:10 字数 3231 浏览 0 评论 0原文

我最近从 Rails 6.1 迁移到 7.0,当我尝试注册用户时,我不断收到错误消息。

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'

有些事情告诉我,我需要在用户模型中实现一些属性,也许是因为我对电子邮件进行了验证。我已经尝试过

include ActiveModel::Serialization

  attr_accessor :email

  def attributes
    {'email' => nil}
  end

但没有任何作用。

这是我的用户模型

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

这是我的带有 ActiveModelSerializers 的序列化器

class UserSerializer < ActiveModel::Serializer
              # Basic
  attributes :id, :email, :uid, :firstname, :lastname
end

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

面犯桃花 2025-01-19 11:00:10

无论您在何处初始化序列化程序,都需要包含活动模型序列化。

例如,在您的 /application_controller.rb 中:

class ApplicationController < ActionController::API
    include ActiveModel::Serialization
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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文