Problem compiling

Hi all,

I have a project structure that includes inside the lib directory a mix / tasks directory. In here I have 4 ex files;

create_slugs.ex
import_skills.ex
seed_data.ex
seed_helpers.ex

I’ve ran, from the root directory, my iex -S mix, which seems to work fine (if I run mix compile I hit a couple of minor errors), but then if I go back to run create_slugs.ex I get cannot load module errors (same for the others as well);

** (CompileError) create_slugs.ex:57: module Ecto.Query is not loaded and could not be found

The code for that failed module load is;

defmodule Mix.Tasks.CreateSlugs do
  @shortdoc """
  Creates slug for projects and accounts
  """

  use Mix.Task

  alias Platform.Repo
  alias Platform.Accounts.Account
  alias Platform.Projects.Project

  def run(_args) do
    Mix.Task.run("app.start")

    ## Account

    Mix.shell().info("Creating slugs for Account")

    {with_slug, failed} =
      Account
      |> list_records_without_slug()
      |> create_slugs(:name)

    Mix.shell().info("#{with_slug} created, #{failed} failed.")

    ## Project

    Mix.shell().info("Creating slugs for Project")

    {with_slug, failed} =
      Project
      |> list_records_without_slug()
      |> create_slugs(:title)

    Mix.shell().info("#{with_slug} created, #{failed} failed.")

    :ok
  end

  defp create_slugs(records, field) do
    Enum.reduce(records, {0, 0}, fn record, {with_slug, failed} ->
      record
      |> Ecto.Changeset.change()
      |> Platform.Helpers.ChangesetHelpers.maybe_put_slug(field)
      |> Repo.update()
      |> case do
        {:ok, _} ->
          {with_slug + 1, failed}

        {:error, _} ->
          {with_slug, failed}
      end
    end)
  end

  defp list_records_without_slug(schema) do
    import Ecto.Query

    schema
    |> where([s], is_nil(s.slug))
    |> Repo.all()
  end
end

Other ones can’t load the project module, platform.ex, which is also in my root directory, so I suspect the project hasn’t been compiled.

how do you do this?

1 Like

iex create_slugs.ex

well, this error is expected. Why do you run file as iex create_slugs.ex, what do you expect? You want to run mix task, right? Then mix create_slugs

2 Likes

I’ve tried running mix create_slugs, but I get;

** (Mix) The task “create_slugs” could not be found
Note no mix.exs was found in the current directory

My (alas newbie) understanding is mix.exs only resides in the root?

Yes in the root of the project, but it’s a bit different with umbrella applications.

If the project is the so-called umbrella (namely it has an apps/ directory at the root and you have several directories in there and each has its own mix.exs file) then you should find the project to which the mix create_slugs task belongs and run the command from its root.

Example:

umbrella-project/
  apps/
    one/
      ...
    two/
      mix/
        tasks/
          create_slugs.ex

The above would mean that you have to do this:

cd umbrella-project/apps/two/
mix create_slugs

Better yet, show us an excerpt of your file tree, showing where exactly the Mix tasks files are located, and we can point you at the right way to invoke them.

2 Likes

Thats my tree structure.

Then you should be able to invoke the tasks from the root of the project’s directory.

If not, then you should construct a minimal Git repo demonstrating the issue and link it here. Then we could help you further.