Подтвердить что ты не робот

Rails - отображение ссылок на внешние ключи в форме

Я делаю простое упражнение с двумя моделями. Спорт и команды, определенные как

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

(Примечание: причина, по которой я использую строительные леса, быстро прототипирует, чтобы я мог учиться/экспериментировать с теми частями, с которыми я еще не знаком)

Проблема в том, что мой "спорт" (т.е. ссылка на внешний ключ) выглядит следующим образом: enter image description here

Так получилось это странное обозначение #<blahl blah>...

<%= 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 %>

Я попытался изменить одну строку на @team.sport.name, но это приводит к ошибке undefined method 'Ice Hockey' for #<Team:0x3e7e040>... Любые идеи о том, как правильно отображать имя отсюда?

4b9b3361

Ответ 1

Вы используете text_field для ссылки на существующий объект, здесь select с параметрами Sports as будет более уместным.

Здесь он должен быть изменен:

<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>

f.select будет генерировать поле выбора в HTML, варианты будут иметь все виды спорта в вашей БД.

Некоторая документация об этом:

Чистым способом было бы установить переменную @sports в вашем контроллере и вызвать ее в ваших представлениях:

# 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>

Дополнительная информация:. Если вы хотите "предварительно выбрать" вариант для выбора, вы должны передать его в качестве второго аргумента помощника options_for_select:

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]