首页 > 解决方案 > 从另一个数据库表中自动填充一个数据库表。导轨 API

问题描述

我们在 Rails API 中使用 Devise,并有一个包含 NAME 和 EMAIL 以及其他常用注册信息的用户表。我们还有一个 Tutor profile 表,它与用户是 one_to_one 关系。我们想要的是,当新用户注册时,来自个人用户记录的 NAME 和 EMAIL 会自动填充他们的 Tutor 个人资料表作为默认值。这是我们的导轨模型。任何帮助将不胜感激。谢谢!!:-)

class Tutor < ApplicationRecord
  # delegate :email, :email=, to: :user
  after_initialize :set_defaults

  def set_defaults
    self.image_url ||= "https://cdn.icon-icons.com/icons2/1378/PNG/512/avatardefault_92824.png"
    self.bio ||= ""
  end

  belongs_to :user
end


class User < ApplicationRecord

  has_one :tutor#, dependent: :destory
  after_create :init_tutor
  # accepts_nested_attributes_for :tutor
  # delegate :email, :email=, to: :tutor

  def init_tutor
    self.create_tutor
  end

  def generate_jwt
    JWT.encode({ id: id,
                exp: 60.days.from_now.to_i },
               Rails.application.secrets.secret_key_base)
  end
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

        # validates :fullname uniqueness: { case_sensitive: false }, presence: true  #, allow_blank: false, format: { with: /\A[a-zA-Z0-9]+\z/ }
end

标签: ruby-on-railsrubydatabaseapi

解决方案


注意:具有相同字段和相同数据的请求通常被认为是糟糕的数据库设计。您可以相当容易地从导师对象中查找用户的姓名和电子邮件地址(例如,委托方法)并在进行查询时使用连接。如果这适用于您的应用程序,那么它是一种比复制数据更好的方法,如下所示。

您可以使用以下内容创建与用户具有相同名称和电子邮件的导师:

class User < ApplicationRecord

  has_one :tutor, dependent: :destroy
  after_create :init_tutor

  def init_tutor
    create_tutor(email: email, name: name)
  end

但是,我通常建议不要在活动记录中使用before或钩子,因为它对该记录有任何影响(例如,创建不同的记录、发送电子邮件等)。after在大型应用程序中做过这样的事情后,我的经验是,随着时间的推移,这条路会导致疯狂。这意味着创建或更新对象可能会创建或更新其他对象,这些对象可能会创建或更新其他对象或具有其他副作用,因此很难理解或预测保存记录可能会做什么。

相反,我建议使用ServiceObject模式(或类似模式)。这看起来像:

class UserCreator
  def call(user_params)
    user = User.create(params)
    user.create_tutor(params.slice(:name, :email))
    user
  end
end

随着应用程序的增长,这种模式会变得更好,并且您需要一个地方来做一些事情,比如发送电子邮件、排队后台作业、更新用户数等等。


推荐阅读