简体   繁体   中英

How to select columns from preloaded data and group in Ecto?

I have 3 tables: sales , products , and sales_products . Sales contains information about sales made as the name implies, products contains information about various products, and sales_products is an intermediary table with a sale_id + product_id composite key, and a quantity field.

My current Ecto query looks like this:

    query =
      from s in Sale,
      inner_join: sp in SaleProduct,
      on: sp.sale_id == s.id,
      inner_join: p in Product,
      on: p.id == sp.product_id,
      group_by: s.id,
      order_by: [asc: :date],
      preload: [:sale_products]

This works in that I get a result similar to:

[%Sale{
    [...],
    sale_id: ID,
    sale_products: [
      %SaleProduct { product: #Ecto.Association.NotLoaded<association :product is not loaded>, sale_id: ID, product_id: PID }
    ],
    [...]
}]

Firstly, how do I preload 'product' for SaleProduct when it is inside its own preloaded struct?

And secondly, and the main question, how do I select only specific columns from sale_products ? I am trying to return this as a json Object, however I get a Poison error as it does not know how to encode some fields, and I just want to select the fields I need from the SaleProduct struct to rectify this.

I solved this.

To preload product for SaleProduct, you just nest the preload:

preload: [..., saleproducts: [:product], ...]

And to solve the overarching question, you actually don't use preload at all, but rather fragment :

select: %{products: fragment("JSON_ARRAYAGG(JSON_OBJECT('product_id', ?, 'quantity', ?))", sp.product_id, sp.quantity)}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM