Jump to content

The ultimate community for Ruby on Rails developers.


nested form with has_many through add same resource with different types

  • Please log in to reply
No replies to this topic

#1 helmerj



  • Members
  • 1 posts

Posted 15 August 2013 - 10:59 AM



I have a rather complex data model with a very deeply nested form. Basically I am fine using nested forms and have already many resources that I can add dynamically using the cocoon gem in a rails 4.0 application. So I do know all bout accepts-nested_attribute for calls and adding the attribute to the permit call in the parent controller in rails 4.0.


One problem puzzles me though. I have a PostalAddress model. Each postal address has_many geographic_boundaries through postal_address_boundaries.


has_many :postal_address_boundaries
has_many :geographic_boundaries, through: :postal_address_boundaries

accepts_nested_attributes_for :postal_address_boundaries, allow_destroy: true, reject_if: :all_blank

The geographic_boundaries are nested by their type (postal_code > city > subburb) so they have a different type and are associated with each other with a selfreferencing parent-child association model. Found this great post to actually do that: http://tesoriere.com...ship-modelling/


What I am trying to do is the following:


In the form for postal_addresses I would like to have three text input fields for a geographic_boundary each. So I thought I could use three different partials to do so. Each contain a select field for now with a different collection to filter the choice depending on the type of geographic_boundary:

= f.simple_fields_for :postal_address_boundaries do |pb|
  = render 'postal_address_boundary_postal_code_fields', :f => pb
= f.simple_fields_for :postal_address_boundaries do |pc|
  = render 'postal_address_boundary_city_fields', :f => pc
= f.simple_fields_for :postal_address_boundaries do |pc|
  = render 'postal_address_boundary_suburb_fields', :f => pc

A sample partial:

    = f.input :geographic_boundary_id, label: "Postal Code",
      :collection => GeographicBoundary.joins(:geographic_boundary_type).where(geographic_boundary_types: {name: "Postal Code"}).order("name ASC"),
      :prompt => t('forms.please_select'), input_html: { class: "postal-code" }

This works on a new postal_address form, when I either build a geographic_boundary in my new controller action or use an after_initialize call in my postal_address model to build the association resource. 

after_initialize :add_child

  def add_child
    self.postal_address_boundary ||= self.postal_address_boundaries.build if self.new_record?

BUT when I update an existing record, I have 9 fields in my form. The three for the existing associations  and 2 empty ones for each of my three partials. 


How can I nest the same resource multiple times but filter the input by the type associated with the nested resource?


I am at a complete loss on how to do this and if I can't find a solution will have to dump rails altogether and have to look for another framework to implement the existing data-model. I know it is possible just don't know how!


Any help would be greatly appreciated. 

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users