Phoenix seed module is not defined

I want to create a seed module to run from my seed script in priv/repo/seeds.ex

The module is in priv/repo/seeds/app_seed.ex and is declared as following

defmodule App.EquipmentSeeder do
  alias App.Repo
  alias App.Equipment

  def add_equipment do
    IO.puts "Hello world"
  end

  def clear do
    IO.puts "delete"
    Repo.delete_all
  end
end

and the script is just doing this

App.EquipmentSeeder.add_equipment

But when i run priv/repo/seeds.ex (or rather mix ecto.reset), i get

undefined (module App.EquipmentSeeder is not available)

It seems like this module is not built, how do I get around this?What is the problem? I have been sitting with this way to long.

Thankful for any help!

2 Likes

Files in the priv/ directory are not compiled but rather executed straight and distinct, you need to put your app_seed.ex file with the module definition someone in your main project.

2 Likes

To add on top of @OvermindDL1’s response, you can adjust which files get compiled by editing elixirc_paths in mix.exs.

I generally avoid creating Seeder modules. E.g. App.EquipmentSeeder.delete is to me somewhat redundant because in 99% of cases I’m running it with echo.reset which cleans up DB beforehand. And, App.EquipmentSeeder.add_equipment could be Factory.insert! instead or using domain modules directly, e.g.: Equipments.create(...). In a few occasions that I did use a separate seed module I either put it in lib/ (which is not ideal because it’s available in :prod Mix env where I definitely don’t want to accidentally run after initial release) or like this:

# priv/repo/seeds.exs
defmodule Seeder do
  # ...
end

Seeder.do_this()
Seeder.do_that()
3 Likes

It is correct that i needed to add the folder to elixirc_paths
. But the problem actually was me naimng the extension of the file wrong. I hade made it a script file “.exs” instead of “.ex”. So embarasing but hopefully this might help someone else :slight_smile:

Thanks for the helpful answers!

If you add the folder to elixirc_paths, then the code will be compiled and shipped with your project, and you don’t want that because it is needed only for seeding. Instead, you can keep the file as app_seed.exs and do this at the top of your seeds.exs:

Code.require_file("app_seed.exs", __DIR__)
8 Likes