Ruby on rails ArgumentError:Google oauth回调中的参数数目错误

Ruby on rails ArgumentError:Google oauth回调中的参数数目错误,ruby-on-rails,ruby,oauth,devise,google-oauth,Ruby On Rails,Ruby,Oauth,Devise,Google Oauth,我随后将用户身份验证添加到我的rails应用程序中。本教程使用Desive和google_oauth2 当用户尝试登录Google时,用户在回调后遇到ArgumentError 错误: 用户模型和回调控制器之间出现了一些问题,但我有点太过紧张,无法理解是什么导致了这个问题 user.rb class User < ApplicationRecord # Include default devise modules. Others available are: # :confirm

我随后将用户身份验证添加到我的rails应用程序中。本教程使用Desive和google_oauth2

当用户尝试登录Google时,用户在回调后遇到ArgumentError

错误:

用户模型和回调控制器之间出现了一些问题,但我有点太过紧张,无法理解是什么导致了这个问题

user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  devise :omniauthable, omniauth_providers: [:google_oauth2]

  def self.from_google(email:, full_name:, uid:, avatar_url:)
   create_with(uid: uid, full_name: full_name, avatar_url: avatar_url).find_or_create_by!(email: email)
  end
end
class用户
omniauth\u回调\u控制器.rb

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def google_oauth2
    user = User.from_google(from_google_params)

    if user.present?
      sign_out_all_scopes
      flash[:success] = t 'devise.omniauth_callbacks.success', kind: 'Google'
      sign_in_and_redirect user, event: :authentication
    else
      flash[:alert] = t 'devise.omniauth_callbacks.failure', kind: 'Google', reason: "#{auth.info.email} is not authorized."
      redirect_to new_user_session_path
    end
  end

  protected

  def after_omniauth_failure_path_for(_scope)
    new_user_session_path
  end

  def after_sign_in_path_for(resource_or_scope)
    stored_location_for(resource_or_scope) || root_path
  end

  private

  def from_google_params
    @from_google_params ||= {
      uid: auth.uid,
      email: auth.info.email,
      full_name: auth.info.name,
      avatar_url: auth.info.image
    }
  end

  def auth
    @auth ||= request.env['omniauth.auth']
  end
end

class Users::OmniAuthCallbackController
我猜(!!)您正在运行ruby的最新版本:
3.0.0
,该版本是在编写该教程之后于2020年12月发布的

ruby版本3中有一个重大的突破性变化:

错误非常微妙,但之所以会发生,是因为您的代码正在执行以下操作:

User.from_google(
  {
    uid: auth.uid,
    email: auth.info.email,
    full_name: auth.info.name,
    avatar_url: auth.info.image
  }
)
(即,将一个
散列
传递给该方法),而不是:

User.from_google(
  uid: auth.uid,
  email: auth.info.email,
  full_name: auth.info.name,
  avatar_url: auth.info.image
)
(即,将关键字参数传递给方法。)

解决此问题很容易:可以使用“double splat”运算符(
***
)将哈希转换为关键字参数:

user = User.from_google(**from_google_params)

如果您在阅读类似教程时对代码进行这样的修改感到不舒服,那么使用较旧的ruby版本(例如
2.7
)也应该很好。我上面展示的代码的“固定”版本在所有ruby版本上都能正常工作。

我猜你正在运行ruby的最新版本:
3.0.0
,该版本在该教程编写后于2020年12月发布

ruby版本3中有一个重大的突破性变化:

错误非常微妙,但之所以会发生,是因为您的代码正在执行以下操作:

User.from_google(
  {
    uid: auth.uid,
    email: auth.info.email,
    full_name: auth.info.name,
    avatar_url: auth.info.image
  }
)
(即,将一个
散列
传递给该方法),而不是:

User.from_google(
  uid: auth.uid,
  email: auth.info.email,
  full_name: auth.info.name,
  avatar_url: auth.info.image
)
(即,将关键字参数传递给方法。)

解决此问题很容易:可以使用“double splat”运算符(
***
)将哈希转换为关键字参数:

user = User.from_google(**from_google_params)

如果您在阅读类似教程时对代码进行这样的修改感到不舒服,那么使用较旧的ruby版本(例如
2.7
)也应该很好。我上面展示的代码的“固定”版本在所有ruby版本上都能正常工作。

all ruby versions>2就是这样。你真是个传奇!插入
**
成功了。我现在遇到了另一个问题,尝试使用Google登录时返回“验证失败:密码不能为空”。有什么办法可以解决这个问题吗?我可以通过为用户创建一个随机密码来解决密码问题。从技术上讲,ruby v2.1.0中首先引入了必需的关键字参数,所以OP的代码必须至少需要这个版本才能以其当前的形式工作。此外,在这一点上,我只是假设没有人在使用像1.8.7或1.9.3这样的古老版本,除非他们明确地声明其他版本。所有ruby版本都>2,也就是说。你是一个传奇!插入
**
成功了。我现在遇到了另一个问题,尝试使用Google登录时返回“验证失败:密码不能为空”。有什么办法可以解决这个问题吗?我可以通过为用户创建一个随机密码来解决密码问题。从技术上讲,ruby v2.1.0中首先引入了必需的关键字参数,所以OP的代码必须至少需要这个版本才能以其当前的形式工作。此外,在这一点上,我只是假设没有人在使用像1.8.7或1.9.3这样的古老版本,除非他们明确说明了其他情况。