user3515316
user3515316

Reputation: 13

Saving a foreign key in my form when a user selects a name from the dropdown menu

I am a newbie to Ruby on Rails and am stumped. As part of my exercise I am creating an app that let's people put in their goal, a description, a deadline and assign it to a person.

I've got two models, a user model and a goal model. In my ERB form to create a new goal, I've created a dropdown menu of all the created users but now I have no idea how to convert that into the foreign key that gets saved.

<%= form_for(@goal) do |f| %>
  <% if @goal.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@goal.errors.count, "error") %> prohibited this goal from being saved:</h2>

......

    <div class="field">
       <%= f.label :user_id, "Whose goal is it?" %><br>
       <%= collection_select(:goals, :user_id, User.all, :id, :name, prompt: true ) %>
    </div>

  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

The above seems to create the dropdown menu I need. I just have no idea how to get from the :name generated in the dropdown to the :user_id associated with it to submit.

Will greatly appreciate your help.

Thanks!

Upvotes: 0

Views: 1346

Answers (2)

Martin M
Martin M

Reputation: 8668

Frist you should use singular as object in collection_select:

<%= collection_select(:goal, :user_id, User.all, :id, :name, prompt: true ) %>

Then your collection_select creates a select tag with name goal[user_id]. It will look like

    <select name="goal[user_id]">
      <option value="">Please select</option>
      <option value="1" selected="selected">D. Heinemeier Hansson</option>
      <option value="2">D. Thomas</option>
      <option value="3">M. Clark</option>
    </select>

The options have user IDs as value an the names as content. So the parameter

params[:goal][:user_id]

contains the ID of the selected user. This is exactly how Rails expects the foreign key.

See the documentation of collection_select

Adition: there are great gems to simplify form generation, i.e. simple_form which reduces your form to

<%= simple_form_for(@goal) do |f| %>
  ...  
  <%= f.association :user %>
<% end %>

Upvotes: 3

Plamena Gancheva
Plamena Gancheva

Reputation: 700

Your question is already answered but I'd like to share an awesome tutorial I found:

Advanced forms

Just add to your 'new' controller

@user_options = User.all.map{|u| [ u.name, u.id ] }

Then in your form:

 <%= f.select(:user_id, @user_options) %>

Upvotes: 2

Related Questions