1

How do you get fields_for to submit an array? Everything I've found suggested on SO doesn't work for me.

My params are submitting like this:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxHD...VoA==", "callsign"=>"baz", "post"=>{"conversation_attributes"=>{"missives_attributes"=>{"content"=>"Hello"}}}}

but I want them to submit like this, with the square brackets around missives:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxHD...VoA==", "callsign"=>"baz", "post"=>{"conversation"=>{"missives"=>[{"content"=>"Hello"}]}}}

I just want to submit a single instance of missive, but in array form. In other words, an array with single member.

This answer lists all the possible ways to get this working, and I have failed with every single one:

FAIL 1

_post_form.html.erb

<%= f.fields_for :conversation do |ff| %>
  <%= ff.fields_for 'missives[]', [] do |fff| %>
    <%= fff.text_area :content %>
    ...
  <% end %>
<% end %>

Result: Error: undefined method `id' for []:Array

FAIL 2

It is an ActiveRecord relationship so apparently I do not need getter/setter methods.

<%= f.fields_for :conversation do |ff| %>
  <% @missives = [] %>
  <%= ff.fields_for :missives, @missives do |fff| %>
    <%= fff.text_area :content %>
    ...
  <% end %>
<% end %>

Result: Error (undefined method `content' for []:Array)

FAIL 3

<%= f.fields_for :conversation do |ff| %>
  <%= ff.fields_for :missives, @missives do |fff| %>
    <%= fff.text_area :content %>
    ...
  <% end %>
<% end %>

Result: does not put square brackets around missives.

FAIL 4

In the controller:

@missives = [Postmissive.new]

In the post form:

<%= f.fields_for :conversation do |ff| %>
  <%= ff.fields_for :missives, @missives do |fff| %>
    <%= fff.text_area :content %>
    ...
  <% end %>
<% end %>

Result: Error (undefined method `content' for Array).

Current state of code:

post.rb

has_one :conversation, class_name: 'Postconversation', dependent: :destroy
accepts_nested_attributes_for :conversation

postconversation.rb

has_many :missives, class_name: 'Postmissive', dependent: :destroy
accepts_nested_attributes_for :missives

postmissive.rb

belongs_to :conversation, class_name: 'Postconversation', foreign_key: 'conversation_id'
validates :content, presence: true

posts_controller.rb

@post = @character.posts.create(post_params)
...

def post_params
  params.require(:post).permit( conversation_attributes: [ missives_attributes: [ :content ] ] )
end

_post_form.html.erb

<%= f.fields_for :conversation do |ff| %>
  <%= ff.fields_for :missives do |fff| %>
    <%= fff.text_area :content %>
    ...
  <% end %>
<% end %>
Bazley
  • 2,699
  • 5
  • 36
  • 61

1 Answers1

4

The answer does not target success/failure of the form or what happens after the form is submitted.

It just targets sending missives as an array.

  <%= f.fields_for :conversation, Postconversation.new do |ff| %>
    <%= ff.label :message %>
    <%= ff.text_field :message %>

    <%= ff.fields_for 'missives_attributes[]', Postmissive.new do |fff| %>
      <%= fff.label :content, [] %>
      <%= fff.text_field :content %>
      <%= fff.text_field :content %>
      <%= fff.text_field :content %>
    <% end %>
  <% end %>

Please note that Postconversation.new and Postmissive.new are just added to make the code work. You HAVE to modify it as per your application logic.

The params output:

{"utf8"=>"✓",
 "authenticity_token"=>"auth_token",
 "post"=>
  {"title"=>"Lorem Ipsum",
   "conversation_attributes"=>
    {"message"=>"Lorem ipsum",
     "missives_attributes"=>
      [{"content"=>"Dolore labore et eos ut quod"},
       {"content"=>"Lorem ipsum"},
       {"content"=>"Lorem ipsum"}]}},
 "commit"=>"Create Post"}
Kartikey Tanna
  • 1,423
  • 10
  • 24
  • Perfect answer. `<%= ff.fields_for 'missives_attributes[]', Postmissive.new do |fff| %>` did the trick. – Bazley Jun 02 '18 at 16:01
  • You can also use `:missives_attributes`. It will be creating a Hash. Try it. – Kartikey Tanna Jun 02 '18 at 16:03
  • You mean `<%= ff.fields_for :missives_attributes, Postmissive.new do |fff| %>`? This gives the same old params: `Parameters: {"utf8"=>"✓", "authenticity_token"=>"mxHD...VoA==", "callsign"=>"baz", "post"=>{"conversation_attributes"=>{"missives_attributes"=>{"content"=>"Hello"}}}}` – Bazley Jun 02 '18 at 16:07