« [Tip] Servoy code coloring for TextMate | Main | [Tip] Popping UP the popupmenu plugin »

August 19, 2007

[Article] Working with record objects

by Karel Broer
Freecolours

As a former Filemaker developer, I disliked words like 'classes', 'objects', 'variables' and other horrible programming words...

Since working with Servoy I began to get a little grip on these things and I especially start to like working with record objects.

"Record objects...?" you say; ".. where the heck do I need that for?" Let me unveil the secrets behind working with record objects, by giving you a few common examples:

Example 1: Assign an organization to a person

First, we start by storing the -selected- person record as an object in a global by doing:

globals.vPersonRecord = forms.mycontacts.foundset.getRecord(forms.mycontacts.foundset.getSelectedIndex())

(You can create this global on the fly, but you can also use Servoy's global media dataprovider.)

Next, show a form in dialog and find an organization. You show the foundset in a list of organizations in the dialog. Then, after performing the search, you want to select an organization from the list and put the organization id in the person record, in a field called 'organization_id'.

To make sure you assign the organization to the right person record, most of the times you now probably perform a search for the person record (or if you are a more enhanced SQL programmer, you perform an UPDATE query).

But we do not need that anymore, we just do this:

globals.vPersonRecord.organisation_id = organisation_id
databaseManager.saveData()

Pretty neat, ain't it?

As long as you perform a 'databaseManager.saveData()' after inserting values in the object, everything goes as smooth as pouring Heineken into a beer glass... :-)

Example 2: Set a related record from the record object in another object global variable

globals.vOrganisationRecord = globals.vPersonRecord.contact_to_organisation.getRecord()
globals.vOrganisationRecord.salesperson_id = globals.vPersonRecord.contact_id //set sales person contact id in organisation record
globals.vOrganisationRecord.field2 = 'blablabla' //other values
databaseManager.saveData()

Example 3: Get records from -many- relations away

Get records from -many- relations away:
globals.vOrganisationAddressRecord = vPersonRecord.contact_to_organisation.organisation_to_address.getRecord()
globals.vOrganisationAddressRecord.street = 'Algolweg'
globals.vOrganisationAddressRecord.nr = ' 9A'
globals.vOrganisationAddressRecord.zip = '3821 BG'
globals.vOrganisationAddressRecord.city = 'Amersfoort'
databaseManager.saveData()

Example 4: I always CREATE a record by doing this

globals.vRecord = forms.mycontact.foundset.getRecord(forms.mycontact.foundset.getSelectedIndex())
databaseManager.saveData()

//insert any value you like
databaseManager.saveData()

That way you're -always- sure you've edited the newly created record.

Example 5

//delete a record
globals.vPersonRecord.deleteRecord()

//duplicate a record
globals.vPersonRecord.duplicateRecord()

Example 6

You could also give a record object to another method as an argument, like:

workFlowMethod(globals.vOrganisationRecord)

Example 7: Retrieve a record object from an other method

var vRecord = arguments[0] //arguments are set as mentioned in example 6

var vOrgID = vRecord.organisation_id
var vName = vRecord.organisation_name
var vSalesperson = vRecord.organisation_to_contact_saleperson.first_last_name

Example 8: Looping through a set of records:

for ( var i = 0; i < mycontacts.foundset.getSize(); i ++) {
    var vRecord = forms.mycontacts.foundset.getRecord(i +1)

    //do whatever, like:
    var vName = vRecord.first_last_name
    var vBirthDate = vRecord.birthdate
    
    databaseManager.saveData()
}

As long as you put the correct fieldnames behind the variable you can alway retrieve ALL record data from the object!

I hope you see the huge advantage of working with records objects!

I wish y'all lot's of fun working with record objects!

| Posted by David Workman on August 19, 2007 at 12:05 PM in Articles | Permalink

Comments

Karel, have you tried this:
//delete a record
globals.vPersonRecord.deleteRecord()

//duplicate a record
globals.vPersonRecord.duplicateRecord()

that does not work!

Posted by: Harjo Kompagnie | Aug 20, 2007 7:50:30 AM

Hi Karel,

I haven't really messed around with record objects much but you've given some food for thought! Thanks. I don't quite understand though how on 4) you are creating a record as it looks like you are just retrieving an existing record...
Example 4: I always CREATE a record by doing this

globals.vRecord = forms.mycontact.foundset.getRecord(forms.mycontact.foundset.getSelectedIndex())
databaseManager.saveData()

//insert any value you like
databaseManager.saveData()

Posted by: John Allen | Aug 20, 2007 5:28:30 PM

John,

that was a typo error by Karel. I am sure he meant

globals.vRecord = forms.mycontact.foundset.getRecord(forms.mycontact.foundset.newRecord())
databaseManager.saveData()

Posted by: Patrick Ruhsert | Aug 21, 2007 12:21:22 PM

And another remark: record variables don't "live" forever. Once the underlaying foundset changes, you cannot be sure that your record is still valid. At least this was the case in older versions of Servoy. So I recommend only to use this in a restricted workflow. Then, however, I would say it is "best practice".

Posted by: Patrick Ruhsert | Aug 21, 2007 12:24:07 PM

Karel, very nice article!

Posted by: David Workman | Aug 24, 2007 12:17:48 PM

My appologies, globals.vRecord = forms.mycontact.foundset.getRecord(forms.mycontact.foundset.getSelectedIndex())
databaseManager.saveData() is indeed a typo...

It should be:
globals.vRecord = forms.mycontact.foundset.getRecord(forms.mycontact.foundset.newRecord())
databaseManager.saveData()

Thank you Patrick for giving the correct answer!

Posted by: Karel Broer | Sep 23, 2007 4:35:46 PM

Thought I would just add a note to this. Probably something everyone else understands but took me a bit to work it out. If you are wanting to grab record objects that are more than one relationship away and some or all of these relationships are one-to-many then you have to be sure to add a 'for' loop for each relationship. So for example with records two relations away you use 'relationship1.setSelectedIndex(i)' in the first loop, then next loop 'relationship1.relationship2.getRecord(j)' to get the actual record. You can add of course whatever actions/selections in between or within those loops to make sure you are getting the record or records you want. If you start with one-to-many and the second relationship is one-to-one then you can leave out the last loop and simply fetch the record with 'relationship1.relationship2.getRecord(1)'. Note though that it is '1' not 'i' as 'i' will return null after the first loop of course.

I imagine most of our relationships are one-to-many and this was probably obvious to most but took me a bit so thought I'd add that in case it helps anyone else. Thanks Karel for this article! It's given me lots of fun playing around with it, using it in different ways.

Posted by: John Allen | Jan 7, 2008 8:52:54 PM

Post a comment