Как настроить form_for в Rails с разными маршрутами? - PullRequest
2 голосов
/ 28 января 2012

проблемный домен

  • У нас есть Projects и Milestones
  • После создания Milestone имеет Project

Маршрутизация

В моем первоначальном подходе у меня было что-то вроде:

  resources :projects do
    resources :milestones
  end

Таким образом, все маршруты RESTful выглядели так: projects/PROJ_ID/milestones/ID

Мне это нравилось, и вам не нужно было Project ID все время: только когда вы создаете Milestone.

Теперь маршруты выглядят так:

  resources :projects do
    resources :milestones, :only => [:new, :create]
  end

  resources :milestones, :except => [:new, :create]

Когда я создаю новый Milestone (первый маршрут):

  • Я использую вложенный ресурс
  • Это чтобы получить Project ID
  • Мы создаем новый Milestone, нам нужен Project ID

С другими Milestone операциями (второй маршрут):

  • Я использую стандартный Milestone ресурс
  • Мы уже работаем с существующим Milestone
  • Milestone уже несет Project ID

Проблема: рендеринг __form.html.erb

Все в порядке, за исключением случаев, когда я получаю представление для new.html.erb и edit.html.erb для Milestone. Они делают _form.html.erb.

Оригинальный подход (все ресурсы вложены)

<%= form_for([@project, @milestone]) do |f| %>
  ...
<% end %>

Из-за вложенного ресурса нам нужно иметь Project и Milestone в качестве параметров.

Тот же код выше работает нормально для new и edit. потому что исходный подход предполагал Project/Milestone вложенную маршрутизацию для всех операций REST.

Текущий подход (только создать / новый вложенный)

Мы хотим, чтобы _form.html.erb выглядело так, когда мы создаем новый Milestone:

<%= form_for([@project, @milestone]) do |f| %>
  ...
<% end %>

И для всех других операций REST на Milestone мы хотим, чтобы _form.html.erb выглядел следующим образом:

<%= form_for(@milestone) do |f| %>
  ...
<% end %>

Итак ...

Текущее решение не очень красиво:

  • Просмотр кода проверяет, называлось ли это «новым» или не «новым» действием
  • Используйте тест "if", чтобы выбрать, какой код (как указано выше) должен выполняться представлением

Это не СУХОЙ, это грязно, и кажется, что должен быть более элегантный способ.

Буду признателен за любой вклад. Очень многое еще подходит для скорости с Rails. Заранее спасибо;)

Ответы [ 2 ]

4 голосов
/ 28 января 2012

Вы можете передать переменную с вашим ресурсом частичному _form.Например:
Новое:

render "form", :resource => [@project, @milestone]

Изменить:

render "form", :resource => @milestone

Внутри формы

<%= form_for resource do |f| %>
  ...
<% end %>
2 голосов
/ 28 января 2012

Я бы обычно поместил содержимое формы в парциальное и записал form_for в каждом файле.

update:

<%= form_for @milestone do |f| %>
  <%= render :partial => 'form', :locals => {:f => f} %>
  <%= f.submit "Update my object" %>
<% end %>

create

<%= form_for [@project, @milestone] do |f| %>
  <%= render :partial => 'form', :locals => {:f => f} %>
  <%= f.submit "Create Object" %>
<% end %>

, поскольку обычно поля формы не меняются, но текст кнопки, идентификаторы форм и т. Д. И т. Д. Могут отличаться.Также дает вам возможность добавлять дополнительные поля, текст и т. Д.

...