Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a function to get Enum descriptions and values. #1724

Open
ketupia opened this issue Jan 21, 2025 · 2 comments
Open

Add a function to get Enum descriptions and values. #1724

ketupia opened this issue Jan 21, 2025 · 2 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@ketupia
Copy link

ketupia commented Jan 21, 2025

The specific need I asked about in my Elixir Forum Post was for a function that supported using Enum descriptions and values for select input options on Phoenix Forms.

Is your feature request related to a problem? Please describe.
Creating a custom Enum invites the opportunity to provide labels or descriptions for the values. There's presently no function that returns the labels and descriptions. It seems a pretty natural fit to leverage the descriptions as labels in Phoenix forms.

Describe the solution you'd like
Add a function to Ash.Type.Enum that returns the labels and descriptions.

Describe alternatives you've considered

  1. I have implemented this myself on my custom types.
  2. Add options_for_select/1 to AshPhoenix. The reason I bring this up is that options_for_select has the labels first where Ash.Type.Enum defines them second. It might be more natural for the function on Ash.Type.Enum to return them the same way they're defined.

Express the feature either with a change to resource syntax, or with a change to the resource interface

On Ash.Type.Enum

  @doc """
  Returns a list of the values and their descriptions.
  """
  @spec labeled_values() :: [{:atom, String.t()}]
  def labeled_values() do
    values()
    |> Enum.map(fn value -> {description(value), value} end)
  end

Or in AshPhoenix...

  @doc """
  Returns a list of the descriptions, value pairs to pass to Phoenix.HTML.Form.options_for_select/2.
  """
  @spec options_for_select(term) :: [{String.t(), :atom}]
  def options_for_select(enum) do
    enum.values()
    |> Enum.map(fn value -> {enum.description(value), value} end)
  end
@chazwatkins
Copy link
Contributor

chazwatkins commented Jan 21, 2025

I'll have some time soon to take a stab at adding this feature. If you don't mind, I have a few questions to make sure the implementation meets the needs properly.

What would you like to happen if the description's are nil?

defmodule MyApp.Types.Status do
use Ash.Type.Enum, values: [:open, :closed] # <- No description provided so `description/1` returns nil
end

If you have more than one nil description, you'll only get one of them returned when calling labeled_values/0.

Is the description for the enum what you want or the string representation of the value?

The description is meant to be as the name suggests, a description of what the enum value is and likely not something you'd put in a select field.

I think this might be more useful for select fields if we did something similar to Phoenix.Naming.humanize/1

  @doc """
  Returns a list of the values by their string representation for use in UI select fields
  """
  @spec labeled_values() :: [{String.t(), :atom}]
  def labeled_values() do
    Enum.map(values(), fn value -> {humanize(value), value} end) # <- [{"Open", :open}, {"Closed", :closed}]
  end

  defp humanize(value) when is_atom(value) do
    value
    |> to_string()
    |> humanize()
  end

  defp humanize(value) when is_binary(value) do
    value
    |> String.replace(~r([^A-Za-z]), " ")
    |> String.capitalize()
  end

Where could this be used in Ash outside of UI select fields?

To your point, this seems like something that would only be used in the UI, so maybe AshPhoenix is a better home for it. But, if everyone wants it in Ash itself, I'm fine with it.

@zachdaniel
Copy link
Contributor

hmm...alright, I think maybe you are right and it should go in AshPhoenix as a helper, that shouldn't base itself on description. They are descriptions, not values. We can make that humanize by default, and have an override to allow setting specific ones etc. It can also have a "use descriptions" option?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
Development

No branches or pull requests

3 participants