srcoulombe

srcoulombe

Struggling to use a Flop join_field for sorting

This might be somewhat related to Sorting by a join field in a query with Flop not working, but I wasn’t able to follow the author’s solution

Context

I have two schemas: one for assets and another for issues.

Assets
# asset.ex
@derive {
  Flop.Schema,
  filterable: [:name],
  sortable: [:updated_at, :ongoing_issues_count],
  adapter_opts: [
    join_fields: [
      ongoing_issues_count: [
        binding: :ongoing_issues_count,
        field: :count,
        ecto_type: :integer
      ]
    ]
  ]
}

schema "assets" do
  field :name, :string
  
  has_many :issues, Issue
end
Issues
# issue.ex
schema "issues" do
  field :title, :string
  field :description, :string
  field :status, Ecto.Enum, values: @supported_statuses, default: :ongoing
end

Intentions

I’m trying to do two things within the Flop table that lists all my assets:

  1. show how many issues with status==:ongoing are associated to each asset, and
  2. allow users to sort the table in increasing/decreasing order based on how many issues with status==:ongoing are associated to each asset

I was able to accomplish 1. by defining the @derive Flop.Schema in the “assets.ex” file:

image

I’m struggling to understand why I can’t sort by the ongoing_issues_count join field though :confused:

Here’s the list_assets function I’m currently working with:

def list_assets(params) do
    ongoing_issues_count_query =
      Issue
      |> where([issue], parent_as(:asset).id == issue.asset_id)
      |> where([issue], issue.status == :ongoing)
      |> select([issue], %{count: count(issue)})

    query =
      Asset
      |> from(as: :asset)
      |> join(
        :left_lateral,
        [asset],
        ongoing_issues_count in subquery(ongoing_issues_count_query),
        as: :ongoing_issues_count
      )
      |> select([asset, ongoing_issues_count], %{
        asset: asset,
        ongoing_issues_count: ongoing_issues_count
      })

    Flop.validate_and_run(query, params, for: Asset)
  end

Thanks in advance to anyone who reads this!

Marked As Solved

srcoulombe

srcoulombe

figured it out - i had one obvious bug, and one smaller mistake.

the smaller mistake was with how i had constructed the ongoing_issues_count_query. I ended up converting it to:

ongoing_issues_count_query =
      Issue
      |> where([issue], parent_as(:asset).id == issue.asset_id)
      |> where([issue], issue.status == :ongoing)
      |> group_by([issue], issue.asset_id)
      |> select([issue], %{asset_id: issue.asset_id, count: count(issue)})

with the outer query being:

query =
      Asset
      |> from(as: :asset)
      |> join(
        :left_lateral,
        [asset],
        ongoing_issues_count in subquery(ongoing_issues_count_query),
        as: :ongoing_issues_count,
        on: ongoing_issues_count.asset_id == asset.id
      )
      |> select([asset, ongoing_issues_count], %{
        asset: asset,
        ongoing_issues_count: coalesce(ongoing_issues_count.count, 0)
      })

the coalesce is there to ensure that null values are converted to 0.

the bigger bug was that my Flop table had

  <:col :let={%{asset: asset, ongoing_issues_count: ongoing_issues_count}} label="Ongoing issues">

instead of

  <:col :let={%{asset: asset, ongoing_issues_count: ongoing_issues_count}} label="Ongoing issues" field={:ongoing_issues_count}>

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

Other popular topics Top

jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 44532 311
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement