I wanted to clean up my controllers by taking advantage of the introduction of FallbackControllers.
While migrating the following snippet, I got stuck how I am able to dynamically reload forms with parameters:
def create(conn, %{"input" => params}) do
changeset = Input.changeset(%Input{}, params)
Bodyguard.permit!(Abilities, :write, conn.assigns.current_user, nil)
case Repo.insert(changeset) do
{:ok, _input} ->
conn
|> redirect(to: path(conn, :index))
{:error, changeset} ->
render(conn, "new.html", changeset: changeset)
end
end
I’m having no problems to utilize the fallback controller to clean up my controller, resulting in the following:
def create(conn, %{"input" => params}) do
changeset = Sport.changeset(%Input{}, params)
with :ok <- Bodyguard.permit(Abilities, :write, conn.assigns.current_user, nil),
{:ok, _input} <- Repo.insert(changeset) do
conn
|> redirect(to: path(conn, :index))
end
end
My problems is reloading the right form in the fallback controller:
def call(conn, {:error, changeset = %Changeset{}}) do
form = if Enum.empty?(conn.path_params), do: "new", else: "edit"
render(conn, "#{Enum.join(conn.path_info, "/")}/#{form}.html", changeset: changeset)
end
I am therefore able to reload a simple form in a generic way. Has any of you ever tried to find a generic way to dynamically reload complex forms with parameters additional to changeset
?
I could define a function for each entity but I don’t really like this approach since it’s not as great as it could be, but that should be doable.
Edit: An idea that came to my mind after posting was that I might define a function in each entity controller that’s called from the fallback controller and returns a map of such parameter names and values.