I have implementations for these myself, but I wanted to suggest the following features. I can turn this into one or multiple PRs based on the implementations included:
attrs/3: This takes the output of build/3 and turns it into a map with string keys.
def attrs(module, type, traits \\ %{}) do
module
|> build(type, traits)
|> from_schema()
end
defp from_schema(struct) do
struct
|> Map.from_struct()
|> Map.drop([:__meta__])
|> Enum.map(fn
{k, %Ecto.Association.NotLoaded{}} -> {to_string(k), nil}
{k, v} when is_struct(v) -> {to_string(k), from_schema(v)}
{k, v} -> {to_string(k), v}
end)
|> Enum.into(%{})
end
update/3: Update a module. I’ve struggled with the name on this one, but update seems to be the best, although change, change_update, or change_and_update might work as well. It isn't strictly needed, and it could probably use some trait resolution of attrs to get a more useful interface for it, so this one could be considered a work in progress.
def update(module, struct, attrs) do
struct
|> Changeset.change(attrs)
|> module.refinery_repo().update!(returning: true)
end
reload/2: Not necessary, but extremely useful because it reuses the refinery_repo().
def reload(module, %schema{} = struct) do
module.refinery_repo().get_by(schema, Map.take(struct, schema.__schema__(:primary_key)))
end
Refactory has about a 70% overlap with our current in-house excessively complex fixture solution (too much meta programming), and the remaining 30% is incompatible because of flaws in our in-house solution. One thing that I will be looking to add for our internal adapter to Refactory is a sort of context management mechanism (like SeedFactory).
I have implementations for these myself, but I wanted to suggest the following features. I can turn this into one or multiple PRs based on the implementations included:
attrs/3: This takes the output ofbuild/3and turns it into a map with string keys.update/3: Update a module. I’ve struggled with the name on this one, butupdateseems to be the best, althoughchange,change_update, orchange_and_updatemight work as well. It isn't strictly needed, and it could probably use some trait resolution ofattrsto get a more useful interface for it, so this one could be considered a work in progress.reload/2: Not necessary, but extremely useful because it reuses therefinery_repo().Refactory has about a 70% overlap with our current in-house excessively complex fixture solution (too much meta programming), and the remaining 30% is incompatible because of flaws in our in-house solution. One thing that I will be looking to add for our internal adapter to Refactory is a sort of context management mechanism (like SeedFactory).