ex_admin
ex_admin copied to clipboard
batch_action exception for uuid id's
I have all my models with uuid for id's instead of integers, when executing a batch_action destroy, ex_admin gives an exception, this is caused because it tries to convert the model id from string to int and given that they are uuid it fails.
def batch_action(conn, defn, %{batch_action: "destroy"} = params) do
resource_model = defn.resource_model
type = case ExAdmin.Schema.primary_key(resource_model) do
nil -> :integer
key -> resource_model.__schema__(:type, key)
end
ids = params[:collection_selection]
count = Enum.count ids
ids
|> Enum.map(&(to_integer(type, &1)))
|> Enum.each(fn(id) ->
repo().delete repo().get(resource_model, id)
end)
put_flash(conn, :notice, "#{count} #{pluralize params[:resource], count} "
<> (ngettext "was successfully destroyed.", "were successfully destroyed.", count))
|> redirect(to: admin_resource_path(resource_model, :index))
end
this is the line that causes the problem
|> Enum.map(&(to_integer(type, &1)))
Deleting line by line works well, only when using the batch options does not
adding this to admin_resource_controller.ex fixes the problem
defp to_integer(:binary_id, string), do: string
I have the same issue. The test suite has a test called "batch selection for binary id" but it's not testing this case, only in case there's no id.
I'm preparing a pull request with the fix.
I'm reopening to pick up the test.
Even with those changes, if the primary key is defined like {:id, Ecto.UUID, autogenerate: true}
, those function headers won't match. Why not use a wildcard catch-all after the :integer
function head?
defp to_integer(:id, string), do: string
defp to_integer(:string, string), do: string
defp to_integer(:binary_id, string), do: string
defp to_integer(:integer, string) do
case Integer.parse string do
{int, ""} -> int
_ -> string
end
end
defp to_integer(_, string), do: string