检入记录是否有效时停止Rails加载关联的模型

时间:2018-07-22 21:31:10

标签: ruby-on-rails ruby activerecord

我有一个名为message的对象,它属于运营商,公司,国家/地区

我允许通过CSV大量插入用户-我之前想要做的是确保在导入之前每一行都是有效的(这样我就可以在开始导入之前通知用户)

因此,我创建了一种方法,该方法循环所有所有新数据并执行Message.new(PARAMS_IN_HERE),然后在其上调用.valid?,这很好并且可以达到预期的结果。

但是,当我查看日志时,会看到类似这样的查询

  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.3ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Company Load (0.2ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Country Load (0.2ms)  SELECT  "countries".* FROM "countries" WHERE "countries"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  Carrier Load (0.2ms)  SELECT  "carriers".* FROM "carriers" WHERE "carriers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]

显然,多次执行相同的查询是很浪费的。有一种方法可以使rails在需要查找/停止时缓存值/预加载吗?

这是我的消息类的样子

class Message < ApplicationRecord
  belongs_to :company
  belongs_to :carrier
  belongs_to :country

  before_validation :set_default_details, on: :create

  private

  def set_default_details
    if self.user.present?
      self.carrier_id = self.user.company.tariff.carrier_id
      self.country_id = self.user.country_id
      self.company_id = self.user.company_id
    end
  end
end  

1 个答案:

答案 0 :(得分:0)

您的验证参考self.user,但您发布的模型代码片段中未定义。

如果您的验证涉及关联对象,例如self.company,则将这些对象提供给构造函数:Message.new(company: company)而不是Message.new(company_id: company.id)。如有必要,可以提前查询所有相关对象-只需一次查询即可-将ID->对象映射存储在哈希中。

类似地,您可以使用诸如company_id之类的验证参考字段,但是最好在各处使用关联对象。