HasManycheckbox() is obviously only one way of updating these relationships. The other main way is via cunning uses of includePartial().
Let’s return to our contact’s email addresses – remember the contact ‘hasMany’ of those. We need a way to a) list their existing email addresses, b) add new ones (preferably within the same update form as the main contact details and c) edit or delete existing addresses.
When you need to display/update more information that what a checkbox could hold, includePartial() comes to the rescue. Whilst I’m demonstrating this with the email address field, which just has a single value, there’s nothing stopping you adding additional fields for this example.
In our Contact’s edit form, we can simply do this:
<fieldset> <legend>Email</legend> #includePartial(contact.emailaddresses)# #includePartial("emailaddressNew")# </fieldset>
And then create a partial called _emailaddress.cfm in the /views/contacts/ folder, containing:
<cfoutput> #btextField( objectName="contact", association="emailaddresses", position=arguments.current, property="email", label="Email Address", class="span4" )# </cfoutput>
This should look pretty familiar – after all, it’s *almost* the same as a bog standard textField on a model, except we’re listing the association, and crucially, the postition.
So if we’ve got multiple email addresses, what does the generated HTML look like?
<label class="control-label" for="contact-emailaddresses-2-email">Email Address</label> <input class="span4" id="contact-emailaddresses-2-email" maxlength="500" name="contact[emailaddresses][email]" value="firstname.lastname@example.org" type="text"> <label class="control-label" for="contact-emailaddresses-3-email">Email Address</label> <input class="span4" id="contact-emailaddresses-3-email" maxlength="500" name="contact[emailaddresses][email]" value="email@example.com" type="text">
The [emailaddresses][email] part of the naming convention translates to “object[association][id][property]”.
And when submitted, with params.contact, we can see a nested struct:
If we’ve included the association when we do the contact updating, i.e (contact.update(params.contact);) these properties will automatically update, with no extra code.
Right, that’s all for now – thoughts on improving this greatly recieved.