How to combine two selected fields in a form

advertisements

I'm trying to combine the values of two select fields in a form into a single variable before submitting the form.

Here is the just of my code:

In new.html.erb (for RoR):

<%= form_for :character, url: characters_path, method: :post do |f| %>
  <p>
     <%= f.label :alignment %><br>
     <%= f.select :alignment_lr, options_for_select([" ","Chaotic","Neutral","Lawful"], disabled: " ", selected: " ") %>
     <%= f.select :alignment_ud, options_for_select([" ","Good","Neutral","Evil"], disabled: " ", selected: " ") %>
  </p>
<% end %>

This generates the following html:

<p>
  <label for="character_alignment">Alignment</label><br>
  <select id="character_alignment_lr" name="character[alignment_lr]">
    <option disabled="disabled" selected="selected" value=" "> </option>
    <option value="Chaotic">Chaotic</option>
    <option value="Neutral">Neutral</option>
    <option value="Lawful">Lawful</option></select>
  <select id="character_alignment_ud" name="character[alignment_ud]">
    <option disabled="disabled" selected="selected" value=" "> </option>
    <option value="Good">Good</option>
    <option value="Neutral">Neutral</option>
    <option value="Evil">Evil</option></select>
</p>

How can I combine the values selected for :alignment_lr and :alignment_ud to equal something like alignment.value = alignment_lr.value + ' ' + alignment_ud.value?

I am open to using javascript or jquery in order to resolve this.


It's actually not necessary to use scripting at all. You appear to have no real interest in keeping the components of your alignment variable as separate fields in your model, so the short answer is: don't do it.

You can use virtual attributes to record a value in your form and then apply logic in your model to create the actual value that gets saved to the database via ActiveRecord. Virtual attributes allows your form to have fields that do not directly correspond to fields in your model.

1) Create a migration that drops your "alignment_lr" and "alignment_ud" coluumns and replaces them with a single column "alignment." Ideally, you would have your database normalized in such a way that every alignment combination is saved to an alignments table, and you'd be saving a key, rather than a dynamically generated string, but this is a different issue;

2) In your Character.rb model, add an attr_accessor line:

class Character < ActiveRecord::Base

  attr_accessor: :alignment_lr, :alignment_ud

3) In your characters_controller.rb file, add :alignment_lr and :alignment_ud to your strong params (character_params method)

4) You can still write your f.select statements exactly as you already have them.

5) In your characters_controller.rb create method:

@character.combine_alignment(@character.alignment_lr, @character.alignment_ud)

6) In your Character.rb, add the combine_alignment method:

def combine_alignment(left_right, up_down)
  return "#{left_right} #{up_down}"
end