СУШКА помощника: оберните form_for и получите доступ к локальной переменной формы

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

Мой помощник выглядит примерно так:

def simple_form_helper(record_or_name_or_array, *args, &proc)
    options = ... # overriding some options, not relevant
    form_for(record_or_name_or_array, *(args << options.merge(:option => "blah")) , &proc)

    # i wish to access  &proc and append the call to render 
    # to within &procs scope (to access block local variable)
    concat render('shared/forms/submit')     # this obv does not work

end

в shared/forms/_submit.erb у меня есть набор полей и кнопок отправки, которые являются общими для множества моделей. Итак, я хочу, чтобы это отображалось из области видимости form_for, чтобы был доступ к f.

 f.text_field :foo
 f.hidden_field :bar
 f.submit "Save"

Идея состоит в том, чтобы использовать его так в представлениях:

simple_form_helper :object do |f|
  f.text_field :name
  f.text_field :description
  f.text_field :other_field
  # want common fields and submit button appended here

  # I could just call render("shared/forms/submit") here
  # but that does not seem very DRY. Or am I too unreasonable?
end

Таким образом, он работает как старый добрый form_for: создает форму для некоторого :object со специфическими для него полями. А затем добавляет партиал с полями, которые являются общими для множества моделей.

Есть ли способ сделать это? Возможно, есть лучший способ?

Спасибо!


person Swartz    schedule 28.06.2011    source источник
comment
Вы также могли бы использовать частичный макет.   -  person rubish    schedule 29.06.2011
comment
Я просмотрел рендер с :partial и :laout... но не смог передать переменную формы, чтобы заставить ее работать. Напишите пример, если можете. Спасибо   -  person Swartz    schedule 29.06.2011


Ответы (2)


почти уверен, что это сработает

def simple_form_helper(record_or_name_or_array, *args)
   options = ... # overriding some options, not relevant
   form_for(record_or_name_or_array, *(args << options.merge(:option => "blah"))) do |f|
       yield f if block_given?
       concat f.text_field :foo
       concat f.hidden_field :bar
       concat f.submit "Save"  
   end
end

и вы также можете вызвать simple_form_helper :object без блока, если вам не нужно добавлять какие-либо поля

person mike    schedule 28.06.2011
comment
Теперь, когда я это вижу, так очевидно :). Единственное, что нужно добавить concat перед каждым вызовом помощника формы после yield. Или не возвращается. Например. concan f.text_field :foo. Спасибо! - person Swartz; 28.06.2011
comment
о, правые помощники делают все эти сумасшедшие concat-вещи, рад, что это помогло! Я отредактирую ответ, чтобы он был правильным - person mike; 28.06.2011
comment
Да меня все время сбивает с толку. Насколько я знаю, рельсы 3 делают это намного проще и логичнее. Но это приложение для рельсов 2.3.x, которое я поддерживаю. - person Swartz; 29.06.2011

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

Частичный макет:

<%= form_for(record_or_name_or_array, :class => my_local_variable) do |f| %>
  <%= f.hidden_field :some_field %>

  <%= yield f %>

  <%= f.submit "Save" %>
<%- end %>

Шаблон или часть, где использовать макет:

<%= render :layout => "partial_layout_name", :locals => {:my_local_variable => value} do |f| %>

  <%= f.text_field :more_fields_here %>

<%- end %>
person rubish    schedule 29.06.2011
comment
не могли бы вы взглянуть на мою проблему, пожалуйста: stackoverflow.com/questions/12598203/ Очень похоже, но я не знаю, что делать... - person Dmitri; 26.09.2012