How to simplify `case` iteraction when the code is almost the same

↘锁芯ラ 提交于 2019-12-11 14:30:00

问题


I have this code in my controller:

def search(conn, %{"q" => param}) do
    locale = conn |> get_session(:locale)
    case locale do
      "pt" ->
        searchEmpresas = Skeleton.Customers.Empresa |> Skeleton.Customers.search_pt(param)
        searchLojas = Skeleton.Customers.Loja |> Skeleton.Customers.search_pt(param)
        searchEventos = Skeleton.News.Evento |> Skeleton.News.search_pt(param)
      "es" ->
        searchEmpresas = Skeleton.Customers.Empresa |> Skeleton.Customers.search_es(param)
        searchLojas = Skeleton.Customers.Loja |> Skeleton.Customers.search_es(param)
        searchEventos = Skeleton.News.Evento |> Skeleton.News.search_es(param)
      "fr" ->
        searchEmpresas = Skeleton.Customers.Empresa |> Skeleton.Customers.search_fr(param)
        searchLojas = Skeleton.Customers.Loja |> Skeleton.Customers.search_fr(param)
        searchEventos = Skeleton.News.Evento |> Skeleton.News.search_fr(param)
      "de" ->
        searchEmpresas = Skeleton.Customers.Empresa |> Skeleton.Customers.search_de(param)
        searchLojas = Skeleton.Customers.Loja |> Skeleton.Customers.search_de(param)
        searchEventos = Skeleton.News.Evento |> Skeleton.News.search_de(param)
      _ ->
        searchEmpresas = Skeleton.Customers.Empresa |> Skeleton.Customers.search(param)
        searchLojas = Skeleton.Customers.Loja |> Skeleton.Customers.search(param)
        searchEventos = Skeleton.News.Evento |> Skeleton.News.search(param)
    end
    render(conn, "search.html", searchEmpresas: searchEmpresas, searchLojas: searchLojas, searchEventos: searchEventos)
  end

The code is the same except for the ending _pt/es/de/fr in the search function.
Is there a way to simplify this greatly?
Is there a way to generate this code as we do in Phoenix Templates using:

<%= for i <- ["pt", "es", "de", "fr"] do %>
   i ->
        searchEmpresas = Skeleton.Customers.Empresa |> Skeleton.Customers.search_<%=i%>(param)
        searchLojas = Skeleton.Customers.Loja |> Skeleton.Customers.search_<%=i%>(param)
        searchEventos = Skeleton.News.Evento |> Skeleton.News.search_<%=i%>(param)
<%end%>

回答1:


Is there a way to simplify this greatly?

Yes, you can first generate the function name as an atom dynamically using if/2 and then use apply/3 to call it.

def search(conn, %{"q" => param}) do
  locale = conn |> get_session(:locale)
  f = if locale in ~w(pt es fr de), do: :"search_#{locale}", else: :search
  searchEmpresas = apply(Skeleton.Customers, f, [Skeleton.Customers.Empresa, param])
  searchLojas = apply(Skeleton.Customers, f, [Skeleton.Customers.Loja, param])
  searchEventos = apply(Skeleton.News, f, [Skeleton.News.Evento, param])
  render(conn, "search.html", searchEmpresas: searchEmpresas, searchLojas: searchLojas, searchEventos: searchEventos)
end

Is there a way to generate this code as we do in Phoenix Templates using:

You could use macros for this, but I'd use the code above which uses apply/3.



来源:https://stackoverflow.com/questions/44987417/how-to-simplify-case-iteraction-when-the-code-is-almost-the-same

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!