質問

I am using Datamapper and want to join all columns of a related table (1:1 relationship) in the result set. Hence, my code reads as follows:

$p = new Project();
$arrAll = $p->where("id <", 100)->where_related('outboundform', 'reference_type', 'project')->include_related('outboundform')->get()->all_to_array();
print_r($arrAll);

The query works, but no column of table 'outboundform' shows up in the result, they get completely ignored!! I just checked and the generated SQL reads:

SELECT `project` . * , `outboundform`.`id` AS outboundform_id, `outboundform`.`reference_type` AS outboundform_reference_type, `outboundform`.`reference_id` AS outboundform_reference_id, `outboundform`.`created` AS outboundform_created, `outboundform`.`updated` AS outboundform_updated, `outboundform`.`v1` AS outboundform_v1, `outboundform`.`v2` AS outboundform_v2, `outboundform`.`v3` AS outboundform_v3, `outboundform`.`v4` AS outboundform_v4, `outboundform`.`v5` AS outboundform_v5 FROM (`project`) LEFT OUTER JOIN `outboundform` outboundform ON `project`.`id` = `outboundform`.`reference_id` WHERE `project`.`id` <100 AND `outboundform`.`reference_type` = 'project' LIMIT 0 , 30

which is OK and gives me the correct result when executed. What's Datamappers problem here? Why is it not return the full amount of columns?

役に立ちましたか?

解決

The related outboundform row's properties should be accessible in the result object prefixed with the relation's name. So the id becomes outboundform_id, the reference_type becomes outboundform_reference_type and so on.

The problem is that all_to_array() doesn't transfer those to the array version of results. If you want to include them you will have to explicitly list them:

$arrAll = $p->/* snip */->all_to_array(array('id', 'name', 'outboundform_id', 'outboundform_reference_type')); // Project fields and outboundform fields too

If you have an instance of any model, you can get the list of fields by the $instance->fields property of that model (from the database table), and use those to create the list for the all_to_array call by creating prefixed names for the included relation.

Alternatively, if you only need the [] way of accessing fields, you can implement ArrayAccess interface like this:

class DataMapper2 extends DataMapper implements ArrayAccess
{ 
    public function offsetSet($offset, $value)
    {
        if (is_null($offset)) {
            throw new ErrorException('model instances doesn\'t support pushing new fields');
        } else {
            $this->{$offset} = $value;
        }
    }
    public function offsetExists($offset)
    {
        return isset($this->{$offset});
    }
    public function offsetUnset($offset)
    {
        unset($this->{$offset});
    }
    public function offsetGet($offset)
    {
        return isset($this->{$offset}) ? $this->{$offset} : null;
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top