【问题标题】:Programmatically Preload has_many, through: in Elixir Ecto以编程方式预加载 has_many,通过:在 Elixir Ecto 中
【发布时间】:2015-07-09 05:36:22
【问题描述】:

我正在尝试以编程方式将预加载附加到我的一个具有has_many, through: 关系的模型的查询中。

我的模块:

defmodule MyApp.Chemical do
  use MyApp.Web, :model

  schema "chemicals" do
    has_many :company_chemicals, MyApp.CompanyChemical
    has_many :companies, through: [:company_chemicals, :companies]

    field :name, :string
  end

  def with_companies(query) do
          from  chem      in query,
     left_join: comp_chem in assoc(chem, :company_chemicals),
          join: company   in assoc(comp_chem, :company),
       preload: [companies: company]
  end

end

defmodule MyApp.Company do
  use MyApp.Web, :model

  schema "companies" do
    has_many :company_chemicals, MyApp.CompanyChemical
    has_many :chemicals, through: [:company_chemicals, :chemicals]

    field :name, :string
  end
end

defmodule MyApp.CompanyChemical do
  use MyApp.Web, :model

  schema "company_chemicals" do
    belongs_to :chemical, MyApp.Chemical
    belongs_to :company, MyApp.Company
  end
end

使用这些模型,MyApp.Chemical.with_companies/1 可以按预期工作,返回一个查询,该查询将生成一个带有填充 :companies 字段的化学品,但我试图创建如下函数,以通过关联表以编程方式预加载字段:

def preload_association(query, local_assoc, assoc_table, assoc_table_assoc) do
       from  orig in query,
  left_join: association_table in assoc(orig, ^assoc_table),
       join: distal in assoc(association_table, ^assoc_table_assoc),
    preload: [{^local_assoc, distal}]
end

但是,由于preload: [{^local_assoc, distal}] 行,此函数将无法编译。

如何预加载一个 has_many 的关联?谢谢。

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    您是否以任何方式过滤您的联接?因为,如果你不是,你应该调用 preload 来代替:

    query = from c in MyApp.Company, where: ...
    companies = Repo.all(query)
    companies_with_chemicals = Repo.preload(companies, :chemicals)
    

    或者:

    query = from c in MyApp.Company, preload: :chemicals
    companies_with_chemicals = Repo.all(query)
    

    它也会更快,因为它会执行两个单独的查询,将要处理的整体结果集大小从 companies_size * chemicals_size 减少到 companies_size + chemicals_size

    请注意,您还应该能够加入 has_many :through

    【讨论】:

    • 无论如何,我都会改进master以保证你的查询也能运行。它没有任何问题。
    • 这正是我需要看到以解决我自己的问题。谢谢!
    • 有没有办法预加载由关联表上的列过滤的:chemicals?例如“只获取具有 X 属性的化学品”?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多