I was wondering exactly what ash.setup
does and what makes it more powerful than the Ecto variant? The reason I’m asking is that the Ash Framework book writes:
“To roll back a migration, Ash also provides an ash.rollback Mix task, as well as ash.setup, ash.reset, and so on. These are more powerful than their Ecto equivalents — any Ash extension can set up their own functionality for each task” - Ash Framework
and the hex doc writes:
“Runs all setup tasks for any extension on any resource/domain in your application.”
Also in my project generated with the phx.gen has this Ecto.setup
line:
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"]
Ecto is, by design, very lightweight. As an example it doesn’t have the concept of resource snapshots or anything like that.
Ash, and its migration tools, work much more like the equivalent in django or rails.
If you have postgres for the data layer then ash setup will call that data layer’s setup.
From AshPostgres.DataLayer
it’s
def setup(args) do
# TODO: take args that we care about
Mix.Task.run("ash_postgres.create", args)
Mix.Task.run("ash_postgres.migrate", args)
[]
|> AshPostgres.Mix.Helpers.repos!(args)
|> Enum.all?(&(not has_tenant_migrations?(&1)))
|> case do
true ->
:ok
_ ->
Mix.Task.run("ash_postgres.migrate", ["--tenant" | args])
end
end
The point is extensibility, if some other extension does it’s setup unrelated to ecto, that will work to. Each extension has it’s own setup.
Also, since ash_postgres
is wrapped around ecto, it does have some extra functionality. For instance, it takes care for you the tenant migrations if you have any.
Okay, so it is the extensions part that is unique for the ash.setup
? 
Yes. For instance there is also mix ash.codegen
which
Runs all codegen tasks for any extension on any resource/domain in your application.
Ash is like legos. 
Yes, it’s really create for applications with a certain complexity! Every time I learn a new and small part of Ash I can cut away some code and handle it more elegantly.
1 Like