Passing Modulename into a function as a parameter is that possible?

Hi I want to make my function more modular and eventually wrap it into a closure.

I currently have this function:

  def get_all_perfume_by_name_con_sex(query, name, concentration, gender) do 
    from p in query,
      join: j in Fumigate.Fragrance.PerfumeCompanyJoin, where: p.id == j.perfume_id,
      where: [perfume_name: ^name, 
              concentration: ^concentration,
              gender: ^gender
      ],
      select: j.company_id 
  end

I was curious how to pass a module into a function as a parameter more specifically the Fumigate.Fragrance.PerfumeCompanyJoin line.

Is this possible?

  def get_all_perfume_by_name_con_sex_modulename(query, name, concentration, gender, modulename) do 
    from p in query,
      join: j in modulename, where: p.id == j.perfume_id,
      where: [perfume_name: ^name, 
              concentration: ^concentration,
              gender: ^gender
      ],
      select: j.company_id 
  end

Is something like that possible?

I want to eventually wrap the new function into a closure.

Thanks!

Yeah, it should be possible. The module names are just atoms

1 Like

I got it.

Here’s snippet of my original code before refactor.

model/context whatever fragrance/perfume.ex:

   1 defmodule Fumigate.Fragrance.Perfume do
   2   use Ecto.Schema
   3   import Ecto.Changeset
   4   import Ecto.Query
   5   import Fumigate.Helpers.PerfumeHelper
   6   import Fumigate.Helpers.ChangesetHelper
   7
  79   def get_all_perfume_by_name_con_sex(query, name, concentration, gender) do
  80     from p in query,
  81       join: j in Fumigate.Fragrance.PerfumeCompanyJoin, where: p.id == j.perfume_id,
  82       where: [perfume_name: ^name,
  83               concentration: ^concentration,
  84               gender: ^gender
  85       ],
  86       select: j.company_id
  87   end

The problem is that I have two model/context, (fragrance/perfume.ex and approval/perfume_approval.ex) , that share this function the def get_all_perfume_by_name_con_sex(query, name, concentration, gender) do.

The only difference is the module name for the join table is different (Fumigate.Fragrance.PerfumeCompanyJoin vs Fumigate.Approval.PerfumeApprovalCompanyJoin).

I decided to create some closure function and move the whole thing into one place a helper function named import Fumigate.Helpers.PerfumeHelper (this is like a mixin/trait/whatever).

So my refactor code.

perfume_helper.ex

   1 defmodule Fumigate.Helpers.PerfumeHelper do
   2   import Ecto.Changeset
   3   import Ecto.Query
...
  73   def get_all_perfume_by_name_con_sex_module(
  74     query, name, concentration, gender, module_name) do
  75     from p in query,
  76       join: j in ^module_name, where: p.id == j.perfume_id,
  77       where: [perfume_name: ^name,
  78               concentration: ^concentration,
  79               gender: ^gender
  80       ],
  81       select: j.company_id
  82   end
  83 end

fragrance\perfume.ex

  76   def get_all_perfume_by_name_con_sex(query, name, concentration, gender) do
  77   get_all_perfume_by_name_con_sex_module(query, name, concentration, gender, 
Fumigate.Fragrance.PerfumeCompanyJoin)
  78   end

approval\perfume_approval.ex

  76   def get_all_perfume_by_name_con_sex(query, name, concentration, gender) do
  77   get_all_perfume_by_name_con_sex_module(query, name, concentration, gender,
 Fumigate.Approval.PerfumeApprovalCompanyJoin)
  78   end

Thanks MidigoF!

3 Likes