Не так давно в распоряжении Rails-программистов появился метод form for, который позволяет сэкономить пару строчек кода, во время написания шаблонов форм. Используя этот метод, мы можем превратить такой стандартный шаблон:


<% form_tag users_path do %>
  <%= text_field :user, :name %>
  <%= text_field :user, :email %>
<% end %>

в такой:


<% form_for :user, :url => users_path do |f| %>
  <%= f.text_field, :name %>
  <%= f.text_field, :email %>
<% end %>

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

Но что делать, если вы хотите использовать сразу несколько моделей в рамках одной формы? В такой ситуации нам на помощь придёт метод fields for, который переопределяет объект, к которому будут принадлежать поля, находящиеся в его блоке.

Всё просто, давайте разберём следующий пример. В одной и той же форме мы хотим редактировать данные и пользователя, и его кредитной карты:


<% form_for :user, :url => users_path do |f| %>
  <%= f.text_field, :name %>
  <%= f.text_field, :email %>

  <% fields_for :credit_card do |cf| %>
   <%= cf.text_field :number %>
   <%= cf.text_field :holder_name %>
  <% end %>

<% end %>

Используя fields_for в примере выше, мы получили возможность описать сразу две модели в одной форме. Теперь в контроллере у нас доступны и params[:user] и params[:credit_card].

Эта тема так же подробно раскрывается в эпизоде 73 от Railscasts.

8 комментариев:

  1. Sergey:

    собственно достаточно form_for @user do

  2. Strock:

    А тема связей между моделями раскрыта? Ну, дабы дополнительного кода в контроллере не было.

  3. Илья:

    Srtock: да, смотри рейлскаст.

  4. Sanches:

    Информация не очень понятна, но все равнг пригодиться

  5. Alex:

    Спасибо пригодиться

  6. Igor:

    А как подружить сообщения об ошибках для разных моделий друг с другом

    <%= error_messages_for :credit_carde %> <%= error_messages_for :user %>

  7. Igor:

    Еще вопрос. Как быть… Я использую два объекта в одной форме как в статье, первая проблема с ошибками, а вторая с if @user.save && @address.save Первый объект сохраняется после удачного прохождения валидации а второго еще нет. Как сделать, что бы могли сохранится два объекти или не сохранится вообще(при ошибке в одном из них). Заранее благодарен.

  8. Илья Сабанин:

    Метод error_messages_for может принимать несколько символов моделей, для которых нужно вывести ошибки:

    error_messages_for :user, :credit_card
    

    А вот в ответ на второй ваш вопрос я, наверное, напишу отдельную заметку, потому что решение не такое тривиальное.

Извините, но комментарии для этой статьи уже закрыты.