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,
Popular mistakes when using nested forms - makandra dev
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.