form_for не-AR модель - fields_for атрибут Array не повторяется - PullRequest
9 голосов
/ 25 ноября 2011

У меня проблемы с получением fields_for для работы с атрибутом Array модели, отличной от ActiveRecord.

Дистиллировано, мне нужно следующее:

Модели / parent.rb

class Parent
  extend ActiveModel::Naming
  include ActiveModel::Conversion
  include ActiveModel::Validations
  extend ActiveModel::Translation

  attr_accessor :bars
end

Контроллеры / parent_controller.rb

def new_parent
  @parent = Parent.new

  @parent.bars = ["hello", "world"]
  render 'new_parent'
end

Вид / new_parent.html.haml

= form_for @parent, :url => new_parent_path do |f|
  = f.fields_for :bars, @parent.bars do |r|
    = r.object.inspect

С кодом, указанным выше, моя страница содержит ["hello", "world"] - то есть результат inspect, вызванный для массива, присвоенного bars. (С пропуском @parent.bars в строке fields_for я просто отображаю nil).

Как заставить fields_for вести себя так же, как для ассоциации AR - то есть выполнить код в блоке один раз для каждого члена моего bars массива?

Ответы [ 3 ]

11 голосов
/ 03 января 2012

Я думаю, что правильная техника:

= form_for @parent, :url => new_parent_path do |f|
  - @parent.bars.each do |bar|
    = f.fields_for "bars[]", bar do |r|
      = r.object.inspect

Вполне возможно, что это не может быть сделано для Just Work, я не уверен, но, похоже, это помогает.

1 голос
/ 01 октября 2015

Я думаю, что это можно сделать без необходимости каждого из них:

= form_for @parent, :url => new_parent_path do |f|
  = f.fields_for :bars do |r|
    = r.object.inspect

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

class Parent
  def bars_attributes= attributes
  end
end

И вам также необходимо убедиться, что объекты в массиве реагируют на постоянные (поэтому вы не можете использовать строки): (

0 голосов
/ 04 ноября 2017

Я отказался от fields_for и добавил несколько: true

= form_for @parent, :url => new_parent_path do |f|
  - @parent.bars.each_with_index do |bar, i|
    = f.text_field :bars, value: bar, multiple: true, id: "bar#{i}"
...