首页 > 解决方案 > 使用服务器端功能将自定义字段添加到用户模型,同时利用设计进行初始身份验证

问题描述

我在 Rails 5 Web 应用程序中使用 Devise 进行身份验证。我的用户注册视图都是设计生成的,我在表单中添加了一些字段,以便能够在前端动态生成 PGP 密钥。我为这些额外的关键字段创建了一个数据库迁移,并且它们正在正确保存。现在我正在尝试添加一些我在服务器端创建的不是用户输入字段的字段。

这是我的注册控制器:

class User::RegistrationsController < Devise::RegistrationsController
  before_action :sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

  def show
    @user = User.find(params[:id])

  end

  private
  def sign_up_params
    params.require(:user).permit(
        :handle,
        :pin,
        :email,
        :password,
        :password_confirmation,
        :pgp_privatekey,
        :pgp_publickey
    )
  end
end

现在,我想弄清楚的是保存不是用户输入结果的字段的“最佳”方法(例如,基于他们的 IP 地址的纬度/经度估计,或者像比特币这样的东西完全在服务器端生成的地址)。我觉得这可能最适合在我的控制器中在最初调用注册控制器期间完成,也许在最初发生注册时完成。但由于它不是用户驱动的,我不确定在我的控制器中的哪个位置添加这个逻辑是有意义的。

我在我的用户模型中实现了一个名为“generate_bitcoin_keypair”的方法,我想将生成的字段保存在数据库中正确的用户记录中,但我试图了解是否应该通过扩展基础将其添加到我的初始注册代码中使用 super() 调用和资源块设计功能,或者将其放在其他地方是否有意义?显然,现在该方法是在我的 User.rb 模型代码中定义的,我可以在我的控制器中调用它,但我只是想了解这是否是我想要完成的最好、最简洁的方法。

这是我的用户模型:

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

  def self.generate_bitcoin_keypair
    key = Bitcoin::Key.generate()
    {:btc_addr => key.addr, :btc_privkey => key.priv}
  end
end

我是否应该在我的注册控制器中实现一个创建方法,该方法基本上调用用户模型的 generate_bitcoin_keypair 代码,然后将其保存给相应的用户(基于会话 [:id])?

我正在尝试了解实现此目的的最佳方法,如果我的问题不清楚,请告诉我。

我在想这样的事情可能会奏效:

  def create
    super do
      btcdata = User.generate_bitcoin_keypair()
      resource.btc_address = btcdata.btc_addr
      resource.btc_privatekey = btcdata.btc_privkey
      resource.save
    end
  end

在我的registration_controller.rb中,但由于用户记录已经创建并保存在数据库中,我在想它可能应该在edit方法而不是create方法中,我并不完全清楚在哪里确切的逻辑应该坐下来。

谢谢你。

标签: ruby-on-railsrubymodel

解决方案


我不会把它放在控制器中。就像你提到的,这不是用户驱动的行为。我认为这是创建新用户所固有的行为。因此,我将保留在模型中生成比特币密钥对并在回调User中调用它的逻辑ActiveRecord

require 'bitcoin'
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  before_create :generate_bitcoin_keypair

  def generate_bitcoin_keypair
    key = Bitcoin::Key.generate()
    self.btc_address = key.addr
    self.btc_privatekey = key.priv
  end
end

这将生成比特币密钥对并将属性分配给用户记录,然后再在数据库中创建它。


推荐阅读