ruby-on-rails - 从另一个数据库表中自动填充一个数据库表。导轨 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
解决方案
注意:具有相同字段和相同数据的请求通常被认为是糟糕的数据库设计。您可以相当容易地从导师对象中查找用户的姓名和电子邮件地址(例如,委托方法)并在进行查询时使用连接。如果这适用于您的应用程序,那么它是一种比复制数据更好的方法,如下所示。
您可以使用以下内容创建与用户具有相同名称和电子邮件的导师:
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
随着应用程序的增长,这种模式会变得更好,并且您需要一个地方来做一些事情,比如发送电子邮件、排队后台作业、更新用户数等等。
推荐阅读
- python - FTP:Azure VM 上的 421 数据超时
- javascript - 在“返回”之前调用“oDataModel.read”
- angular - 如何以角度分隔管理和用户区域
- python - 如何在 python 中的 OpenCv 中添加自定义 Keras 模型
- python - 当我们通过掩码的阈值图像时,cv2.normalize 实际上会做什么?
- matlab - 通过 Matlab 将任意波形上传到 DS345
- python - 同步两个信号
- ruby - 在 WSL 中使用 Rubymine 的问题
- python-3.x - 如何将多个事件添加到 tkinter 中的绑定
- xslt - 按总和结果分组