sezaru

sezaru

Aggregates with filter arguments

In my system, I have the following resources:

defmodule Core.Feedbacks.Student do
  relationships do
    alias Core.Feedbacks

    has_many :feedbacks, Feedbacks.Feedback

    many_to_many :classes, Feedbacks.Class do
      through Feedbacks.StudentClass
      join_relationship :student_classes

      source_attribute_on_join_resource :student_id
      destination_attribute_on_join_resource :class_id
    end
  end
end

defmodule Core.Feedbacks.Class do
  relationships do
    alias Core.Feedbacks

    has_many :feedbacks, Feedbacks.Feedback

    many_to_many :students, Feedbacks.Student do
      through Feedbacks.StudentClass

      source_attribute_on_join_resource :class_id
      destination_attribute_on_join_resource :student_id
    end
  end
end

defmodule Core.Feedbacks.StudentClass do
  relationships do
    alias Core.Feedbacks.{Student, Class}

    belongs_to :student, Student do
      primary_key? true
      allow_nil? false
      attribute_writable? true
    end

    belongs_to :class, Class do
      primary_key? true
      allow_nil? false
      attribute_writable? true
    end
  end
end

defmodule Core.Feedbacks.Feedback do
  relationships do
    alias Core.Feedbacks

    belongs_to :student, Feedbacks.Student do
      allow_nil? false
      attribute_writable? true
    end

    belongs_to :class, Feedbacks.Class do
      allow_nil? false
      attribute_writable? true
    end
  end
end

As you can see, the Student resource has a many_to_many relationship with the Class resource and both resources have a has_many relationship with the Feedback resource.

I wan´t to create an aggregate that will tell me how many feedbacks a student has inside a class.

If I just wanted all the student feedbacks, an aggregate like this in my Student resource would work just fine:

count :total_feedbacks, :feedbacks

But I want to count all the feedbacks that are from that student and from an specific class, meaning that I would to, somehow, pass an :class_id argument to inside that count aggregate filter expression.

I’m not sure how to solve that using aggregates

Marked As Solved

zachdaniel

zachdaniel

Creator of Ash

So, what I’m about to show you wont’ work, but what you would want is this:

    calculate :total_lessons_in_class,
              :integer,
              expr(first(classes, query: [filter: expr(class_id == ^arg(:class_id))], field: :total_lessons)) do
      argument :class_id, :string, allow_nil?: false
    end

However, you can’t use an aggregate as the field of another aggregate. However, you can do this:

    calculate :total_lessons_in_class,
              :integer,
              expr(count(classes.lessons, query: [filter: expr(class_id == ^arg(:class_id))])) do
      argument :class_id, :string, allow_nil?: false
    end

Assuming that lesson has class_id on it.

Last Post!

sezaru

sezaru

Yep, this worked great, thanks again!

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
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
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

Other popular topics Top

jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
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
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40165 209
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
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