Rails - Displaying Foreign Key References in a for

2019-02-02 15:27发布

I'm doing a simple exercise with two models. Sport and Teams, defined as

rails g scaffold sport name:integer
rails g scaffold team name:integer fans:integer sport:references

(Note: The reason I'm using scaffold is rapidly prototyping so I can learn/experiment with the parts I'm not familiar with yet)

Problem is that my "sport" (i.e. the foreign key reference) is showing like the following enter image description here

So it's got that weird #<blahl blah> notation to it...

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

      <ul>
      <% @team.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
     <div class="field">
    <%= f.label :fans %><br />
    <%= f.number_field :fans %>
  </div>
  <div class="field">
    <%= f.label :sport %><br />
    <%= f.text_field :sport %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

I've tried changing the one line to @team.sport.name but it results in an error undefined method 'Ice Hockey' for #<Team:0x3e7e040>... Any ideas how to properly display name from here??

1条回答
Explosion°爆炸
2楼-- · 2019-02-02 15:45

You are using a text_field for referencing an existing object, a select with Sports as options would be more appropriate here.

This is where it has to be changed:

<div class="field">
  <%= f.label :sport %><br />
  <%= f.text_field :sport %>
</div>

To:

<div class="field">
  <%= f.label :sport %><br />
  <%= f.select :sport_id, options_for_select(Sport.all.map{|s|[s.name, s.id]}) %>
</div>

The f.select will generate a select box in HTML, the options will me all the sports in your DB.

Some documentation about it:

A cleaner way would be to set a variable @sports in your controller and call it then in your views:

# in controller
def edit
  @sports = Sport.scoped
  #...

# in edit view
<div class="field">
  <%= f.label :sport %><br />
  <%= f.select :sport_id, options_for_select(@sports.map{ |s| [s.name, s.id] }) %>
</div>

Additionnal information: If you want to "pre-select" an option for the select, you have to pass it as the second argument of the options_for_select helper:

options_for_select(@sports.map{ |s| [s.name, s.id] }, params[:sport_id])
# this will select by default the option that matches the value of params[:sport_id]
查看更多
登录 后发表回答