Mel
Mel

Reputation: 2693

Rails 4 - key value pair

I'm trying to make an app in Rails 4.

I've recently asked these 2 questions, and taken the advice in the responses. Rails 4 - how to use enum?

I'm still struggling.

I have a form with an input selector:

<%= f.input :self_governance, as: :select, label: "Select your governance approach", collection: Preference.self_governances.to_a.map { |p| [p.to_s.humanize, p] } %>

When I save this and try it, the select menu shows:

["tier_1", 1]

What I want is to display: Tier 1

At the moment, I have a preference model with:

enum self_governance: {
                          tier_1: 1,
                          tier_2: 2,
                          tier_3: 3,
                          tier_4: 4,
                          tier_5: 5
                        }

  enum autonomy: {
                          tier_11: 1,
                          tier_21: 2,
                          tier_31: 3,
                          tier_41: 4,
                          tier_51: 5
                        }           

I have a preferences show view:

<%= @organisation.preference.self_governance.try(:humanize) %>

Also, when I accept the form problem (for now) and try to render the show page, I get this error:

'["tier_1", 1]' is not a valid self_governance

Can anyone see what I've done wrong?

I just want to save the number 1 in the database, but display the words 'Tier 1'.

Upvotes: 0

Views: 797

Answers (1)

Anthony E
Anthony E

Reputation: 11235

Update your form to properly return a collection of keys and values from your enum. Preference.self_governances is a type of hash object.r Rather than call to_a, just iterate over the keys and values:

<%= f.input :self_governance, as: :select, label: "Select your governance approach", collection: Preference.self_governances.map { |key, val| [key.humanize, key] } } %>

If we look at just the output of: Preference.self_governances.map { |key, val| [key.humanize, key] }

We get the following:

[
  ["Tier 1", "tier_1"], 
  ["Tier 2", "tier_2"]
  ...
]

Note that the first value is what gets shown as the select label and the second value is what gets sent to your controller within the param.

EDIT:

When using an enum, you can assign either the key or value of the enum to the field.

preference.self_governance = 1 # Works
preference.self_governance = :tier_1  # Works
preference.self_governance = "tier_1" # Works

But you can't assign the value as a string:

preference.self_governance = '1'
=> "ArgumentError: '1' is not a valid self_governance"  # Doesn't work, tries to look for key '1' in enum, but doesn't exist.

So make sure you pass the key of the selected enum (i.e. "tier_1") aback to your form or else you ma

Upvotes: 1

Related Questions