MatijaL

MatijaL

Best practices when writing context functions with DB queries

Hello,

I would like to hear your opinion on writing controller/context functions with DB queries.

Let’s say that we have an hypothetical app where people can create projects. We have a show project page but we also have a page where all projects are listed, then in the user area, we have places where we want to list only user projects or a place with only active projects, or 5 latest projects etc. What I mean, on different places inside our app, we need to fetch different projects based on some conditions. How do you approach writing queries in this situation?

Do you write a different function for each of those?

def get_user_projects(user) do
  query = from p in Project, where: p.user_id == ^user.id
  Repo.all(query)
end

def get_user_active_projects(user) do
  query = from p in Project, where: p.user_id == ^user.id and p.status == "active"
  Repo.all(query)
end

def get_user_latest_projects(user) do
  query = from p in Project, where: p.user_id == ^user.id, limit: 5
  Repo.all(query)
end

Or do you create more generic functions which creates a query based on opts

def list_user_campaigns(user, opts \\ []) do
    status = Keyword.get(opts, :status)
    limit = Keyword.get(opts, :limit)

    Campaign
    |> where(user_id: ^user.id)
    |> maybe_add_query_status(status)
    |> maybe_add_query_limit(limit)
    |> Repo.all()
end

defp maybe_add_query_status(query, nil), do: query
defp maybe_add_query_status(query, status), do: where(status: ^status)

defp maybe_add_query_limit(query, nil), do: query
defp maybe_add_query_limit(query, limit), do: limit(query, ^limit)

Or do you maybe take some completely different approach?

Most Liked

dimitarvp

dimitarvp

I’ve seen both and both are fine. Go for what feels better for you.

sbuttgereit

sbuttgereit

I find that if I’m accessing the same basic data with some frequency, but using a lot of different flavors of essentially the same query, I’ll use your second, “generic query” approach. I do this because, for me, it’s easier to mentally deal with a single function with options that I’m using frequently than it is to try to remember many specific function names with few options; indeed I might have trouble remembering if I’ve covered a specific use case previously at all. I also find that the more generic approach is just more flexible because I may be able to mix/match options in ways I didn’t originally intend (this usually works out OK, there can be downsides). If I forget the options, finding my documentation about what’s available and what to worry about is also easier with a generic function/many options.

Now I do use the more specific function method, too, if I know that my calling use cases are narrower and not going to be generally useful. In that case I find the balance shifts to having more natural language like code that specifically names the purpose that the functions provides.

As previously pointed out… it’s really personal or team preference about how/when to the use either of the two approaches. Just don’t let it get you into a bikeshedding trap :slight_smile: .

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
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
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Other popular topics Top

lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
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
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48342 226
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
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement