Joris Ooms
Joris Ooms

Reputation: 12038

Rendering nested form fields in Rails

In our app, we have, among others, these three models:

class PackContent < ActiveRecord::Base
  belongs_to :product
  belongs_to :pack

class Product < ActiveRecord::Base
  has_many :pack_contents
  has_many :packs, through: :pack_contents

class Pack < ActiveRecord::Base
  has_many :pack_contents
  has_many :products, through: :pack_contents
  accepts_nested_attributes_for :pack_contents

A pack has multiple pack_contents, which are basically a product and some specific productvariants. The join table (pack_contents) looks like this:

pack_contents

I am now trying to display these pack_contents in a usable manner, but keep running into a wall.

I have tried:

.pack-product-rows
  - @pack.pack_contents.each do |pc|
    = f.simple_fields_for pc do |p|
      = render :partial => 'pack_product_row', :locals => { :p => p, :pc => pc }

But then, upon saving, I get an error saying:

ActiveRecord::UnknownAttributeError in Admin::PacksController#update
unknown attribute: pack_content

And the form field name attributes are wrong, they don't account for multiple contents as they don't include an index.

When I try this:

.pack-product-rows
  - @pack.pack_contents.each do |pc|
    = f.simple_fields_for :pack_contents do |p|
      = render :partial => 'pack_product_row', :locals => { :p => p, :pc => pc }

It renders every partial twice, which, I suppose, is to be expected.

If i don't loop over the contents and just use simple_fields_for, I get the output I want, but not how I want it. I can render the fields with p.input_field :id and the likes, but I need access to the pack_contents in order to display my data like this: (input fields meant to be hidden)

enter image description here

Not sure how to proceed.

Upvotes: 1

Views: 509

Answers (2)

Vishal S Mujumdar
Vishal S Mujumdar

Reputation: 410

I am assuming that you are trying to build the nested form on the views/packs/show.html.erb where in you have the @pack instance variable initialized to a pack from the database. So on this page you will have a - simple_form_for @pack form inside which you want to nest over the pack_contents. Now the simple_form_fields method of the simple_form gem works just like the fields_for method in rails. Based on that I am giving you the code below. It should work properly but you may have make a few syntactical changes to make it work.

- simple_form_for @pack do |pack_form|
  .pack-product-rows
    - @pack.pack_contents.each do |pack_content|
      = f.simple_fields_for :pack_contents, pack_content do |pack_content_fields|
        = render :partial => 'pack_product_row', :locals => { :pack => @pack, :pack_content => pack_content, :pack_content_fields => pack_content_fields}

Now in the partial pack_product_row you will need to use the three locals passed. You must be already using pack and pack_content but whatever fields for pack_contents you want to display should be written as pack_content_fields.field_name. If your naming convention is correct for all the fields then these fields will be either empty if the pack_content is empty or having the value stored in the database.

Upvotes: 1

Jiř&#237; Posp&#237;šil
Jiř&#237; Posp&#237;šil

Reputation: 14402

I'm not sure if I've understood what you're asking but if you just want an access to the current item being automatically iterated via simple_fields_for, then you can access it through the form builder as p.object.

Upvotes: 1

Related Questions