Nested form and a link to add fields question?

I seem to be stuck on a very steep learning curve in my quest to learn
rails ... essentially from tutorials and the like on the web ... my
profession is accounting so please excuse the lack of sophistication
in my attempt to speak rails or for that matter code it.

I subscribed to Ryan Bate' web site and got much of the idea and
knowledge on how to create this nested form from his screencast on
Deeply Nested Forms. The code "Def of link_to_add_fields" is from his
site and is to be found at the end of this posting.

My Add Contract nested form is as follows, new.html.haml:

       - provide(:title, 'Add Contract')
                %h2 New Contract
                = form_for(@codeline) do |codeline|
                  =render 'shared/codeline_error_messages', object:
codeline.object
                  =render 'fields', codeline: codeline
                  /= link_to_add_fields "Add Codes", codeline, :code
                  /debugger
                  .actions
                     = codeline.submit "Save", class: 'save strong
round'

I could not get the link_to_add_fields to work ... thus the comment

The _fields partial:

              <fieldset><legend>Enter Contract Details</legend>
              = codeline.fields_for :contract do |contract|
              .field
                 = contract.label :name, "AuthNum"
                 %br/
                 = contract.text_field :authnum, :size => 10, :class
=> "ui-state-default"
               .
               .
               .
               </fieldset>
               <fieldset><legend>Enter Client Details</legend>
               = codeline.fields_for :clients do |client|
               .field
                  = client.label :name, "First Name"
                  %br/
                  = client.text_field :f_name, :size => 15, :class =>
"ui-state-default"
                .
                .
                .
                </fieldset>
                <fieldset><legend>Enter Billing Code Details</legend>
                = codeline.fields_for :codes do |code|
                .field
                   = code.label :name, "Code Name"
                   %br/
                   = code.text_field :code_name, :size => 15, :class
=> "ui-state-default"
                 .field
                   = code.label :name, "Status"
                   %br/
                   = code.text_field :status, :size => 10, :class =>
"ui-state-default"
                 .field
                    = code.label :name, "Description"
                    %br/
                    = code.text_field :description, :size =>
25, :class => "ui-state-default"
                  .field
                    = codeline.label :name, "Units Alloc"
                    %br/
                    = codeline.text_field :units_alloc, :precision =>
6, :scale => 2, :size => 10, :class => "ui-state-
                       default"
                 </fieldset>

My intent is to be able to use the link_to_add_fields code so that I
am able to add a complete row of these last four attributes, "Code
Name", "Status", "Description", and "Units Alloc", to my contract
form. The reasoning is that some contracts only have one Code
authorized but other will have more and each contract will differ. You
will also notice that the whole nested form is centered on the join
table 'Codelines'. I read on the web,

    https://makandracards.com/makandra/1346-debug-nested-forms

that if you have an extra attribute in your join table then you have
to base your nested form on the join table. My extra attribute is
"Units Alloc" and the reason for this is that many contracts will have
different constellations of codes(read billing codes) authorized, in
many instances they might be using the same codes but with different
amounts of "Units Alloc" and that is why I needed the Units Alloc in
my join table as an extra attribute.

The application helper follows:

    module ApplicationHelper
          def link_to_add_fields(name, f, association)
           new_object = f.object.send(association).klass.new
           id = new_object.object_id
             fields = f.fields_for(association, new_object,
             child_index: id) do |builder|
              render(association.to_s.singularize + "_fields", f:
builder)
             end
           link_to(name, '#', class: "add_fields", data: {id: id,
           fields: fields.gsub("\n", "")})
           end
          end

Here is my best explanation of the above code that I gleaned from
Ryans' screencast:

'with new object we build an instance of the 'name of' association
record
f.object is the object of the form builder, which is a 'name of form'
instance, then we call the association method on that, which is 'name
of the association' and then we call klass on that, which is the 'name
of the association' model, and then we call new on that to build a new
'name of the association' instance. We then use Ruby's object_id to
give us a unique value, then we call fields_for on the 'name of the
formj' form builder and pass in the 'name of the association'
association and we also pass in the new instance of 'name of the
association', new object, so that the 'name of the form' form builder
will build new fields for that. We then render the 'name of the
partial'_fields partial and pass it the 'name of the form' form
builder and then finally we generate the link_to and return that with
class 'add fields, while passing data attributes id, fields'.

I do not understand the def link_to_add_fields code sufficiently
enough to adapt it such that I am able add a complete row of four
attributes, three from one table and the fourth from the join table.

Hopefully one of you folks can see your way to helping me understand
how to use this code such that I have the right associations listed in
the link_to_add_fileds code.

The codelines.js.coffee file:

    jquery ->
      $('form').on 'click', '.remove_fields', (event) ->
        $(this).prev('input[type=hidden]').val('1')
        $(this).closest('fieldset').hide()
        event.preventDefault()

      $('form').on 'click', '.add_codes', (event) ->
       time = new Date().getTime()
        regexp = new RegExp($(this).data('id'), 'g')
        $(this).before($(this).data('fields').replace(regexp, time))
        event.preventDefault()

I again do not understand what is happening here, but it did not seem
to matter as none of my attempts at putting a link_to_add_fields or a
link to remove them showed up on my form ... so I definitely am over
my head.

I can inform you that my form works just fine without the
link_to_add_fields and it also saves to the appropriate tables, but it
only allows one code per contract and since a contract typically will
have two or more codes, the form is of little use.

So my hope is that one of you folks will help me to be able to add a
row of attributes, 'Code Name', 'Status', 'Description' coming from
the codes table, and 'Units Alloc' coming from the codelines table,
to my "Add a New Contract" form, thereby making it possible to have
more than one code per contract.

Any help or suggestions would be appreciated.

Thanks.

You told us that it doesn’t work, but haven’t given us what error you’re getting. This makes it hard to help you. Plus your explanation is waaaaaaayyyy to long for folks whose reading expertise taps out at a 1 and a 0. ;-).

Thanks Bertly ... that is funny ... but even coders must have
explanations somewhere in there vocabulary ... even before you begin
to code.

My apologies for not being clearer on this issue ... there is no
error ... the links do not show up on my page or if they do, I have
been experimenting a lot, they do not respond to the on click action.
In either case, I do not get an error, my page renders as before and
it is as if the "link_to_add_field" is not there.

I am beginning to suspect that the "link_to_add_fields" definition
that I used, was written for a specific nested form setup, and since
my nested form setup is totally different, and my lack of
sophistication in being able to substitue the correct form builder and
associations in the definition, results in it not recognizing my
attempt to insert fields.

I am beginning to think that I need to learn more about programming
before I attempt this next step.

This would be a wonderful opportunity if you are so inclined .... just
think of it ... you could take this novice through the analysis of
what it is in the "link_to_add_fields" definition and thereby help
this novice to identify what it is in this definition that this novice
needs to address such that it picks up the attributes that he wishes
to add to his form.:slight_smile:

Thanks for your interest.

If you want to learn about rails and programming I suggest starting
with a primer on Ruby programming (sorry I can't recommend a
particular one, but a bit of googling should find one) then work right
through the tutorial at railstutorial.org, which is free to use online
and will give you a good grounding in rails. the other thing you will
need to learn about is html, and if you want to do anything serious
then also javascript.

In terms of your problem above the first thing to do is to look at the
generated html (View > Page Source or similar in your browser) to see
whether the links are there and look ok, but this requires knowledge
of html. Also copy and paste the complete html output into the w3c
html valildator to check it is valid. Often the reason for things not
appearing is that the html is invalid in some way.

Colin

check this
https://github.com/vishalsingh/multiple_upload_photo may be helpful for you.

Regards,

Vishal Singh

Thanks vishal,

The explanaitions of the various entities in the Model-View-Control
pattern is definitely interesting.

Thanks again.