0
votes

I have the following action in my Phoenix app controller:

defmodule TattooBackend.Web.API.V1.StudioController do
  use TattooBackend.Web, :controller

  alias TattooBackend.Repo
  alias TattooBackend.Accounts.Account

  def index(conn, params) do
    studios = Studio

    studios = if params["search"] do
      Studio.search(studios, params["search"])
    end

    studios = studios |> Repo.all |> Repo.preload(:address)

    render conn, studios: studios
  end
end

Is there any way to refactor this code to be more readable?

2
Does this even work correctly when params doesn't have "search"? studios would become nil in that case as far as I can see. - Dogbert

2 Answers

2
votes

Your code wouldn't work when params["search"] is falsy. If it is falsy, studios will get the value nil.

You can do this more elegantly like this:

studios =
  if params["search"] do
    Studio.search(Studio, params["search"])
  else
    Studio
  end
  |> Repo.all
  |> Repo.preload(:address)

The if can be collapsed into a single line as well:

studios =
  if(params["search"], do: Studio.search(Studio, params["search"]), else: Studio)
  |> Repo.all
  |> Repo.preload(:address)
1
votes

You can build more complex queries by reduce over the params, eg allowing the address to be conditionally included:

query = 
  Enum.reduce(params, Studio, fn 
    {"search", search_term}, query -> Studio.search(query, search_term)
    {"include_address", "true"}, query -> Ecto.Query.preload(query, :address)
    # ... additional query building params handled here
    _, query -> query # ignore unrecognised params
  end)

studios = Repo.all(query)
render conn, studios: studios