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.