Form_For New Родственная модель - PullRequest
3 голосов
/ 06 августа 2011

Так что в моем приложении у меня есть модель Person, которая has_many Описания. Теперь мне нужна форма на странице показа каждого человека, чтобы добавить новое описание для этого человека. Пока у меня есть следующая форма. Однако он не передает идентификатор человека в действие «Создать описание».

Форма

<%= form_for @person.descriptions.new do |f| %>

    <fieldset class="input">
        <%= f.label :name %>
        <%= f.text_field :name %>
    </fieldset>

    <fieldset class="input">
        <%= f.label :description %>
        <%= f.text_area :description %>
    </fieldset>

    <fieldset class="button">
        <%= f.submit "Post" %>
    </fieldset>

<% end %>

Переданные параметры

{"utf8"=>"✓",
 "authenticity_token"=>"OQY8Xcfm6wtWHXp9GjFfM4ICX79smPwyvfVcaDn+C2s=",
 "description"=>{"name"=>"Test",
 "description"=>"This is a test"},
 "commit"=>"Post"}

Ответы [ 2 ]

6 голосов
/ 06 августа 2011

Создайте объект описания в действии show для контроллера person, добавив его к объекту person вместо формы

Таким образом, в действии show вы получите

  #You probably have something like this already
  @person = Person.find(params[:id])
  #Now do this
  @description = @person.descriptions.build

затем измените форму для использования @ description

Это не совсем идеальное решение, так как вы найдете эту публикацию обратно в контроллер описания, но вы можете изменить URL в форме_for

Такженеверно полагаться на идентификаторы для поиска записей в действиях контроллера. Кто-то может легко изменить код в браузере, чтобы использовать другой идентификатор для объекта person.Вы должны рассмотреть это очень тщательно.Довольно часто вы обнаружите, что человеку разрешено редактировать только свое собственное описание, поэтому объект current_user, основанный на текущем вошедшем в систему пользователе, часто используется в действиях show и edit при работе с этим сценарием.

Обновление

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

++ ОБНОВЛЕНИЕ 2 ++

В дополнение к вышесказанному, я думаю, что вам действительно нужно использовать form_for @person, затем использовать fields_for: description и добавить accepts_nested_attributes_for:описание вашей модели Person, так что вы получите что-то вроде этого.

<%= form_for @person do |f| %>
  <%= f.fields_for :description do |desc_builder|
    <fieldset class="input">
        <%= desc_builder.label :name %>
        <%= desc_builder.text_field :name %>
    </fieldset>

    <fieldset class="input">
        <%= desc_builder.label :description %>
        <%= desc_builder.text_area :description %>
    </fieldset>
  <%end%>
  <fieldset class="button">
      <%= f.submit "Post" %>
  </fieldset>

<% end %>

В вашей модели Person добавьте следующее

class Person < ActiveRecord::Base
#... Add this line
    accepts_nested_attributes_for :descriptions, :reject_if => proc { |attributes| attributes['name'].blank? && attributes['description'].blank? }
#... ---

Затем в вашем действии show для контроллера personпросто создайте описание, как указано выше

  #You probably have something like this already
  @person = Person.find(params[:id])
  #Now do this
  @description = @person.descriptions.build # add an if @person.descriptions.empty? here if you only ever want one description per person.

Приведенный выше код организует отправку вашей формы в действие обновления контроллера лиц, которое автоматически создаст запись описания.Нет необходимости менять какой-либо другой код контроллера.

это потому, что form_for @person организует переход URL на действие обновления, поскольку это уже существующий человек

Поля_for будуторганизуйте, чтобы поля описания были вложены в поля person в хэше params, которые получает действие обновления.

И, наконец, acceptpts_nested_attributes_for организует, чтобы запись описания создавалась или обновлялась автоматически по мере необходимости.Процесс: reject_if => упорядочивает его так, что если имя и описание не заполнены, новая запись не создается.Очевидно, вы можете включить больше полей, изменить условие или не иметь все это.Что бы ни отвечало вашим требованиям.

Надеюсь, это заставит вас двигаться.Вы можете узнать больше о accepts_nested_attributes здесь, если вы чувствуете необходимость http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

0 голосов
/ 06 августа 2011

Самый простой способ убедиться, что вы получили идентификатор объекта @person в хэше params, это просто добавить его в качестве скрытого поля в вашей форме, например:

hidden_field(:person, :id)

Кроме того, довольночем создание нового описания в вашем представлении, вам, вероятно, следует создать описание шаблона в контроллере Persons.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...