I’m trying to implement a form to edit permissions for roles, using checkboxes to grant permissions, with LiveView 0.19. I have a Role
and a Permission
schema with a many_to_many
relationship like so:
defmodule MyApp.Authorizations.Role do
schema "roles" do
field(:description, :string, null: true)
field(:name, :string)
many_to_many(:permissions, Permission, join_through: "roles_permissions", on_replace: :delete)
timestamps()
end
def changeset(role, attrs) do
role
|> cast(attrs, [:name, :description])
|> put_assoc(:permissions, parse_permissions(attrs))
|> validate_required([:name])
|> unique_constraint(:name)
end
defp parse_permissions(%{"permissions" => permissions_ids}) do
permissions_ids
|> Enum.reject(& &1 == "")
|> Enum.map(&Authorizations.get_permission!/1)
end
defp parse_permissions(_), do: []
end
defmodule MyApp.Authorizations.Permission do
schema "permissions" do
field(:resource, EctoAtom)
field(:action, EctoAtom)
many_to_many(:roles, Role, join_through: "roles_permissions", on_replace: :delete)
end
end
I pretty much copy-pasted the checkgroup input from the Fly.io article and use it in my form like this:
<.checkgroup field={f[:permissions]} options={perms} />
perms
being a list of {"permission name", "permission id"}
tuples. The issue I have now is that, when I edit a role and check a permission, the checkboxes values are nested changesets because of the put_assoc
:
value: [
#Ecto.Changeset<action: :update, changes: %{}, errors: [],
data: #MyApp.Authorizations.Permission<>, valid?: true>
]
How can I make this work correctly?