Hello! Elixir noob here, but I’m really liking it so far. But I’ve run into something that I’m not sure how to express.
I have a few Ecto schemas and some of the schemas reference other schemas. Convention, Talk and Host. A Convention belongs to a single Host and a Talk belongs to a single Convention. The schemas will be a little more complex when I’m done, but that’s a fine example for now.
I’d like to write a function (or functions) in my model that lists all Talks by Convention ID as well as all Talks by Host ID. All the ids are the same type. I’m wondering how I should structure this to make good Elixir and Phoenix code.
I have a few ways I’ve considered it:
Separate functions for each:
def list_talks_by_convention(id) do
# do the queries
end
# etc.
This one seems the simplest, but the multiple function names feels uglier and harder to keep track of.
A Single Function with Multiple Inputs:
def list_talks(convention_id \\ nil, host_id \\ nil) do
# do queries
end
The problem here is that I don’t know how to enforce having a single id. This also means the function takes more inputs than it actually requries.
A Single Function that takes a dictionary or one-of type
I actually don’t know what this would look like, but it seems like the best option.
I was also thinking I could have more private methods that do the actual query, but I also don’t know if that’s good elixir code or if bigger functions are better.
I could also be missing another better way to do this, so I could use any advice, but if there’s a canonical way to do this, I’d like to know.
There is a common convention of composing ecto queries, which often looks like a separate module with functions that take a query as the first argument and return a query. This allows you to pipe through them.
defmodule Talks do
import Ecto.Query
def base, do: Talk
def by_speaker(query \\ base(), speaker_id) do
from t in query, where: t.speaker_id == speaker_id
end
...
end
If you search Google for composable Ecto queries a few blogs will appear showing this in more detail. It’s also in the OTP book from pragprog with the bees on the front.
There is also a method where you pass in a keyword list or map of options/filters and reduce over them to create the query.