自动从一个数据库表填充另一个数据库表.Rails API



我们在rails API中使用设计,并有一个用户表,其中包括NAME和EMAIL以及其他常用的注册信息。我们还有一个导师配置表,它与用户之间的关系是one_to_one。我们想要的是,当一个新用户注册时,来自个人用户记录的NAME和EMAIL将自动作为默认值填充到他们的Tutor配置表中。这是我们的rails模型。任何帮助都将非常感激。谢谢! !: -)

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

然而,我通常建议不要在活动记录中使用beforeafter钩子,因为它们对该记录之外有任何影响(例如,创建一个不同的记录,发送电子邮件等)。在大型应用程序中做过类似的事情后,我的经验是,随着时间的推移,这种方法会导致疯狂。这意味着创建或更新对象可能会创建或更新其他对象,这些对象可能会创建或更新其他对象或产生其他副作用,这使得很难理解或预测保存记录可能会做什么。

相反,我建议使用ServiceObject模式(或类似的)。这看起来像:
class UserCreator
def call(user_params)
user = User.create(params)
user.create_tutor(params.slice(:name, :email))
user
end
end

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

最新更新