Using html generator for a proj. I have an EctoEnum and I am trying to get this into a template to use in a drop down.
In it in a file: defenum AdminRolesEnum, :admin_roles, [:owner, :developer, :admin, :editor, :contributor, :viewer]
I found this on how to make it work, but in reality it’s more complicated. It does work in the CLI though.
I’ve tried adding it to the template (preferred solution) but didn’t work. Ex: <%= select f, :role, AdminRolesEnum |> Enum.map(&to_string(elem(&1, 0))), prompt: "Choose Role"%>
But I get this error: (Protocol.UndefinedError) protocol Enumerable not implemented for AdminRolesEnum of type Atom. I wish this worked as as this is how I’d want it.
The module AdminRolesEnum can’t be directly piped into an Enum.map function, hence the error you’re getting. Elixir modules are actually Atoms behind the scenes if I recall correctly. If you really need/want to use the EctoEnum library, take a look at the functions below. The post you linked pipes the result of the enum map function into the Enum.map, not the module.
Reflection
The enum type StatusEnum will also have a reflection function for inspecting the enum map at runtime.
Having spent around 3 hours on this I’m thinking it’s not worth it. Is there any better way to do this? I mean, passing in a list that is already defined.
Or, do I have just had to hardcode the array inside the template? I hate this solution but it’s all I can get to work right now.
You could store it in the database on a separate table eg an AdminRole schema and admin_roles table with columns for role name and description. There are lots of guides on setting up user roles through associations out there.
If you have a LOT of these, you could even make an enum_select helper that encapsulates the select tag. Bonus points if it reflects on the type of the field given to find the right module to use.
If I run AdminRolesEnum.__enum_map__() |> Enum.map(&to_string(elem(&1, 0))) from iex (or from within the html file)
I get: * 2nd argument: not a tuple
I’m also tried using it in a function like U suggest. I’m so new to Phoenix that I can’t even figure how to pass the function from the controller to the view. Not sure if this would make any difference anyway
I figured it out. Long winded beginner syntax, but fills in my select tag. Converts atoms to strings. AdminRolesEnum.__enum_map__ |> Enum.map(fn x -> Atom.to_string(x) end)