如何仅在 Rails 中从一个 table 到另一个 table 符合特定条件时才插入数据?

How do I insert data only if it matches a certain condition from one table to another table in Rails?

我是 SQL 和一般迁移的初学者,所以我的方法可能在这里完全错误,但请耐心等待 ;)

我有一个 Company 模型,它具有可选的 SMTP 邮件配置属性(如 smtp_addresssmtp_port)。

但是,我现在需要我的用户模型也能够具有 SMTP 配置,因此我创建了一个 SMTPConfiguration 模型,其属性为 addressport 以及与 smtpable。此模型将属于用户或公司模型

我现在想做的是将我在公司 table 中已有的数据迁移到 SMTP 配置 table,这听起来很简单,只是我想创建一个新的 SMTPConfiguration 仅当公司实际设置了 smtp_addresssmtp_port 时。如果 smtp_addresssmtp_port 不存在,则公司不应具有所属的 SMTPConfiguration。

使用 Ruby 条件和 ActiveRecord 可以很容易地做到这一点,但是从我读过的内容来看,使用 ActiveRecord 单独插入行对于大型数据库来说可能真的很长,所以这是一个更好的主意使用原始 SQL。原来我很烂 SQL :( .

我在 Whosebug 上搜索了很多,并使用 this and this,我想出了类似

的东西
execute <<-SQL
  INSERT INTO smtp_configurations (address, port, smtpable_id)
  SELECT (c.smtp_address, c.smtp_port, c.id)
  FROM companies c
  WHERE c.smtp_address <> NULL
SQL

这行不通,因为它没有设置 created_atupdated_atsmtpable_type,但老实说我没有想法。 activerecord-import gem 有什么用吗?

我正在使用 Rails 5.1.4 和 Postgres 10.3

尝试 迁移中的下一个代码:

created_at = Time.current.to_s(:db)
insert_clause = <<-SQL
  INSERT INTO smtp_configurations(
    smtpable_id,
    smtpable_type,
    address,
    port,
    created_at,
    updated_at
  )
  SELECT
    c.id,
    'Company',
    c.smtp_address,
    c.smtp_port,
    '#{created_at}',
    '#{created_at}'
  FROM companies c
  WHERE (c.smtp_address IS NOT NULL) AND (c.port IS NOT NULL)
SQL

execute(insert_clause)

更新:更改了普通代码 Rails。