Rails: нужна помощь в отображении form_for одной модели в представлении другой модели

#ruby-on-rails #view #model #form-for

#ruby-on-rails #Вид #Модель #форма-для

Вопрос:

У меня есть две модели, Character и Statistic. Их взаимосвязь — это статистика Character has_one, а статистика belongs_to Character.

Я сгенерировал каркасы для обеих моделей, и то, что я хочу сделать, это иметь возможность создавать новую статистику, если ее нет, отображать статистическую модель и редактировать статистическую модель, все из представления символов. Я не уверен, как отредактировать контроллеры или написать код в представлении, чтобы это произошло.

Вот некоторый код. Из представления символов:

 <h2>Statistics</h2>
<%= render "statistics/form" %>
  

Однако это выдает мне эту ошибку:

 undefined method `build' for nil:NilClass
Extracted source (around line #1):

1: <%= form_for ([@character, @character.statistic.build]) do |f| %>
2:   <% if @statistic.errors.any? %>
3:     <div id="error_explanation">
4:       <h2><%= pluralize(@statistic.errors.count, "error") %> prohibited this statistic from being saved:</h2>
  

Итак, я предполагаю, что у меня неправильно написана первая строка? Я думал, что это сработает, поскольку я хочу, чтобы каждый экземпляр Statistic принадлежал одному символу, и это создало бы эту связь.

Вот код из Statistics / form:

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

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

<div class="field">
<%= f.label :strength %><br />
<%= f.text_field :strength %>
...
<div class="field">
<%= f.label :charisma %><br />
<%= f.text_field :charisma %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
  

Заранее спасибо за любую помощь. Я уже около недели борюсь с ассоциированием моделей таким образом, и я очень разочарован тем, что все еще не понимаю.

Ответ №1:

Вы можете включить поля статистики в свою символьную форму и автоматически создать ассоциацию, но процесс отличается.

Сначала используйте accepts_nested_attributes_for в вашей Character модели:

 has_one :statistic
accepts_nested_attributes_for :statistic
  

И используйте fields_for в вашей символьной форме:

 <%= form_for @character do |f| %>

  ... all your character fields as generated in your scaffold

  <%= f.fields_for :statistic do |statistic_fields| %>
    ... all your statistic fields using statistic_fields as form object, ie:
    <%= statistic_fields.label :strength %><br />
    <%= statistic_fields.text_field :strength %>
    ...
  <% end %>
  <%= f.submit %>
<% end %>
  

Редактировать: Вы все еще можете использовать partial, если хотите разделить формы:

Измените форму статистики на что-то вроде этого:

 <%= form_for @statistics do |f| %>
  <%= render :partial => "statistics/fields", locals => {:f => f} %>
<% end %>
  

Создайте раздел statistic fields, app/views/statistic/_fields.html.erb содержащий все поля, которые ранее были в приведенной выше форме:

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

И затем вы можете повторно использовать поля статистики в вашей символьной форме следующим образом:

 <%= form_for @character do |f| %>
  ...
  <%= f.fields_for :statistic do |statistic_fields| %>
    <%= render :partial => "statistics/fields", locals => {:f => statistic_fields} %>
  <% end %>
  <%= f.submit %>
<% end %>
  

Комментарии:

1. Хм, я не думаю, что это именно то, что я ищу. Что я пытаюсь сделать, так это исправить эту связь между символом и статистикой, а затем использовать этот код для привязки будущих моделей. У каждого персонажа также будут навыки, умения, экипировка и т.д., Поэтому я не хочу загружать все в форму персонажа. Возможно ли было бы отобразить статистическую модель в представлении символов, а затем иметь ссылку для редактирования статистики, которая была бы отражена в представлении символов? Нужно ли мне для этого создавать новый html.erb-файл в link_to?

2. Я не уверен, что понимаю вашу цель здесь. Это для минимизации работы после создания каркасов для этих вещей? Или вы хотите иметь возможность редактировать статистику (и прочее) в их собственной форме? Я отредактировал ответ, чтобы показать вам способ сделать это.

3. На самом деле я хочу оба. Мне определенно нужен способ редактировать статистику и т.д. В их собственных формах, и я хочу сохранить эти фрагменты кода отдельно, чтобы представление символов не становилось слишком загроможденным. Новый метод, который вы опубликовали, звучит так, как будто он может сработать, поэтому я попробую. Спасибо!

Ответ №2:

Build и create вызываются иначе для отношений has_one, чем для has_many.

С помощью has_many @character.statistic.build работает, но с помощью has_one это нужно сделать следующим образом:

@character.build_statistic и .create_statistic

Я создал приложение, чтобы протестировать его, и разместил его на Github для вас. Я надеюсь, что это поможет.

https://github.com/unixmonkey/Manticore_example