插入时预加载Ecto关联

时间:2018-01-29 08:53:56

标签: elixir phoenix-framework ecto

对于多租户电子商务应用程序,我给出了以下ER模式:

Order has_many OrderProduct belongs_to Product belongs_to Price

使用Ecto,在订单的变更集功能中通过cast_assoc(:order_product)一次性插入带有许多 OrderProduct 订单会很容易

但由于将来可能会删除产品以及 Price ,我还想另外存储 Price 的值 OrderProducts :price:quantity)中的数量。

据我所知,我会有以下选择:

  1. OrderProduct 的变更集功能中,我可以通过产品的ID获取产品并加入价格将{em> Price 的:price添加为 OrderProduct 的更改。这将导致N + 1个查询,因为我必须为 Order 中的每个 OrderProduct 执行该查询(在这种情况下这是可以的,因为我只有一个有限的数字产品订单)。但此外,我更愿意保留模式定义模块的回购。但最重要的是:我在多租户设置中使用不同的模式,因此我需要知道 OrderProduct 的变更集功能中的prefix,以便在正确的prefix上执行查询
  2. 在我的Orders模块中的模式定义之外迭代 OrderProducts ,并添加:price作为对 OrderProduct 变更集的更改:
  3. %Order{} 
    |> Order.changeset(attrs)
    |> iterate_order_products_and_map_price_change(tenant)
    |> Repo.insert(prefix: tenant)
    
    1. 首先使用Ecto.Multi插入订单,然后使用额外的Ecto.Multi.run
    2. 添加关系

      我更喜欢第一种选择,因为在我看来,这将是最干净的方法。

      • 这种情况还有其他或更好的选择吗?
      • 是否可以通过联接产品 Price 预先加载 OrderProduct 在架构外部的插入内容?然后我就不会在{1}中使用{。1}}。

1 个答案:

答案 0 :(得分:1)

Ecto.Changeset.prepare_changes/2是另一种选择,可能是您正在寻找的选项:https://hexdocs.pm/ecto/Ecto.Changeset.html#prepare_changes/2