It is not fault of TranslateBehavior - usage of behaviors on
associated models is tricky a little bit. Let me show you one of
solutions (requires CakePHP 1.2 revision > 7644) which as an addition
implements golden rule of good cakes: fat model.

I will follow your solution with 2 tables, although it is solvable by
self-relations in one table. Note that I'll not bind hasMany
association 'Names' for translated field 'name', I will set recursive
to -1 and request only necessary subset of fields. Queries
optimization is generally smart and with Translatebehavior, this rule
should be printed as bold and gold.

Model Subcategory is pretty obvious:

class Subcategory extends AppModel {
    var $name = 'Subcategory';

    var $belongsTo = 'Category';

    var $actsAs = array('Translate' => 'name');
}

Model Category will define new find method, which will:

- optimize query for categories
- fetch subcategories (hasMany records are fetched in extra query
anyway
  and this way we will have them translated)
- reindex categories array with Category.id
- reindex subcategories array and group it by Subcategory.category_id
- merge both arrays

class Category extends AppModel {
    var $name = 'Category';

    var $hasMany = 'Subcategory';

    var $actsAs = array('Translate' => 'name');

    var $_findMethods = array('translated' => true);

    function _findTranslated($state, $query, $results = array()) {
        if ($state == 'before') {
            return array_merge($query, array(
                'fields' => array('id', 'name'),
                'recursive' => -1
            ));
        } elseif ($state == 'after') {
            if (empty($results)) {
                return $results;
            }

            $ids = Set::extract($results, '{n}.Category.id');

            $data = $this->Subcategory->find('all', array(
                'conditions' => array(
                    'Subcategory.category_id' => $ids
                ),
                'fields' => array('id', 'category_id', 'name'),
                'recursive' => -1
            ));

            if (empty($data)) {
                return $results;
            }

            $data = Set::combine(
                $data,
                '{n}.Subcategory.id',
                '{n}.Subcategory',
                '{n}.Subcategory.category_id'
            );

            $insert = array();
            foreach ($data as $category_id => $subcategories) {
                $insert[$category_id] = array('Subcategory' =>
$subcategories);
            }

            $results = Set::combine($results, '{n}.Category.id',
'{n}');
            $results = Set::pushDiff($results, $insert);

            return $results;
        }
    }
}

In your CategoriesController:

$this->set('categories', $this->Category->find('translated));

And that's all. If you will debug($categories) in view, you will find
out that numeric indexes of arrays will contain PK values - it is
necessary for merging them by Set::pushDiff(), like:

Array
(
    [1] => Array
        (
            [Category] => Array
                (
                    [id] => 1
                    [modified] => 2008-09-22 12:19:06
                    [created] => 2008-09-22 12:18:51
                    [locale] => en
                    [name] => English category
                )
            [Subcategory] => Array
                (
                    [1] => Array
                        (
                            [id] => 1
                            [category_id] => 1
                            [modified] => 2008-09-22 12:19:32
                            [created] => 2008-09-22 12:19:32
                            [locale] => en
                            [name] => English SUBcategory 1
                         )
                    [2] => Array
                        (
                            [id] => 2
                            [category_id] => 1
                            [modified] => 2008-09-22 12:19:32
                            [created] => 2008-09-22 12:19:32
                            [locale] => en
                            [name] => English SUBcategory 2
                        )
                )
        )
)

For iteration in views it doesn't matter imho... Now you can replace
view code

foreach ($categories as $category) {
    ....
    if ($category['Subcategory']) {
        ....

with new version ('Subcategory' will be set only for categories with
some subcategories)

foreach ($categories as $category) {
    ....
    if (isset($category['Subcategory'])) {
        ....

and you should be fine. Enjoy your cake!
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to