Page 1 of 1

Constructor of the delegate class

PostPosted: Tue Mar 30, 2010 2:48 pm
by kevinwen
I'm running into a problem where I need to grasp records of parent class object from the relational table. However, if I want to get that record in each of the validation methods (fieldname__validate()), I need to make the same queries multiple times on each of these validate function, just look like this:

Code: Select all
function relational_table_field1__validate(&$record, $value, &$params){
    $parent_record = df_get_record('parent_table_name', array('parent_table_primary_id' => $record->val('parent_table_primary_id')));

    if (!$parent_record->val('sth')) return false;

    //do something
    return true;
}


I'm thinking if we could have a constructor with the &$record as parameter so we can just call df_get_record() once and the member's value can be used by all methods:

Code: Select all
class tables_relational_tablename {
    var $parent_table_primary_id;
    var $parent_table_sth;

    tables_relational_tablename(&$record){
        $parent_record = df_get_record('parent_table_name', array('parent_table_primary_id' => $record->val('parent_table_primary_id')));
        $this->parent_table_primary_id = $parent_record->val('id');
        $this->parent_table_sth = $parent_record->('sth');
    }
}


So the above validate function would look like this:
Code: Select all
function relational_table_field1__validate(&$record, $value, &$params){
    if (!$this->parent_table_sth) return false;

    //do something
    return true;
}


Can somebody know how we can do that?

Re: Constructor of the delegate class

PostPosted: Tue Mar 30, 2010 3:06 pm
by shannah
Since you are wanting this value to be attached to a particular record (rather than the entire table), you'll want a strategy that will associate these values with a particular record. The delegate class is built once at the beginning of each request and the same instance is used to handle all records, so the sample code you post would run into problems if you wanted $parent_table_primary_id to be different for each record.

There are a couple of strategies you can use for this:

1. Use an array to map recordIDs to the values of interest.
2. Use a calculated field (as these values are cached by xataface - until a change is made to the record).
3. Use the pouch associated with each record (this isn't documented, but Dataface_Record has an array attribute called pouch that allows you to attach data to a record.

Since it is possible to load the same record multiple times (and thus causing duplication in solutions #1 and #3) your best performance would likely be obtained using solution #1.

e.g.

Code: Select all
class tables_mytable {
    var $parent_table_sth = array();
   
    function relational_table_field1__validate(&$record, $value, &$params){
        if ( !isset($this->parent_table_sth[$record->getId()]) ){
            $parent_record = df_get_record('parent_table_name', array('parent_table_primary_id' => $record->val('parent_table_primary_id')));
            $parent_table_primary_id = $parent_record->val('id');
            $this->parent_table_sth[$record->getId()] = $parent_record->('sth');
        return $this->parent_table_sth[$record->getId()];

}
}


Or something along those lines.

Re: Constructor of the delegate class

PostPosted: Tue Mar 30, 2010 3:50 pm
by kevinwen
That's a great idea. I would use the solution#1. However, Is it possible to create a Constructor in case I have to use for something else? If I could, what's the signature of it? Thanks.

Re: Constructor of the delegate class

PostPosted: Tue Mar 30, 2010 3:59 pm
by shannah
yes you can create a constructor. Once again this won't be called for each record, but only once for the whole table. The constructor would take no arguments.

e.g.

Code: Select all
class tables_mytable {
    function __construct(){
        ....
    }



A better solution is generally to use the init() method, which is called once the first time the table is accessed. This method takes a reference to the Dataface_Table object as a parameter so you can do some modifications.

e.g.

Code: Select all
class tables_mytable {
    function init(&$table){
        // do some stuff to the table object
    }
}