如何使用HABTM关系和翻译在CakePHP中查询数据?

时间:2014-03-27 07:24:48

标签: cakephp translation has-and-belongs-to-many relationships

我正在使用Cakephp,并尝试将我的模型设为ActAs'Translation'。但我有一个问题。 我的客户模型关系是:

public $belongsTo = array("User");
public $hasAndBelongsToMany = array(
    'Category' =>
        array(
            'className' => 'Category',
            'joinTable' => 'categories_clients',
            'foreignKey' => 'client_id',
            'associationForeignKey' => 'category_id',
            'unique' => true,
        ),
);

在分类模型中:

public $name = 'Category';
public $hasMany = array(
    'Product'
);
public $displayField = 'title';
public $recursive = 1;
public $actsAs = array(
    'Tree',
    'Translate' => array(
        'title', 
        'alias', 
        'description',
    ),
    'Containable' => array('CategoryTranslations'),
);
public $translateModel = 'CategoryTranslations';
public $translateTable = 'category_translations';

当我从客户端控制器查询以获取所有客户端和相关类别时,我无法获得类别的字段“标题”,“别名”和“描述”。这是我的代码:

    if(isset($this->passedArgs['language_id'])){
        $language_id = $this->passedArgs['language_id'];
    }
    else{
        $language_id = Configure::read('Config.language_site');
    }
    $this->Client->Category->locale = $language_id;
    $this->Client->recursive = 1;
    $this->paginate = array('limit' => 20,'order' => array('User.id' => 'desc'));
    $Clients = $this->paginate();

结果如下:

array(
'Client' => array(
    'id' => '1',
    'user_id' => '1',
    'client_type' => 'tenderer',
    'image' => null,
    'image_list' => null,
    'code' => 'SG0593',
    'name' => 'Oorts',
    'address' => '1000 Huynh Tan Phat',
    'telephone' => '0987654321',
    'fax' => '0983213434',
    'email' => 'nguyentuandat.vn@gmail.com',
    'proxy' => 'Dat Nguyen',
    'position' => 'C.E.O',
    'mobile' => '0987654321',
    'referred_by' => 'noone',
    'order' => null,
    'status' => true,
    'created' => '2014-03-27 00:00:00',
    'modified' => '2014-03-27 00:00:00'
),
'User' => array(
    'password' => '*****',
    'id' => '1',
    'username' => 'admin',
    'group_id' => '1',
    'gender' => 'Male',
    'first_name' => 'Nguyễn',
    'middle_name' => 'Tuấn',
    'last_name' => 'Đạt',
    'email' => 'nguyentuandat.vn@gmail.com',
    'phone_number' => '(+84) 947235313',
    'image' => '/uploads/images/255443_102754699884371_1177788671_n.jpg',
    'status' => true,
    'created' => '2014-01-16 09:26:09',
    'modified' => '2014-01-22 06:47:25',
    'full_name' => 'Nguyễn Tuấn Đạt'
),
'Category' => array(
    (int) 0 => array(
        'id' => '1',
        'parent_id' => '0',
        'type' => 'product',
        'image' => '',
        'order' => '0',
        'status' => true,
        'lft' => '1',
        'rght' => '16',
        'created' => '2014-01-25 00:00:00',
        'modified' => '2014-01-25 00:00:00',
        'CategoriesClient' => array(
            'id' => '1',
            'category_id' => '1',
            'client_id' => '1'
        )
    )
)

你能帮帮我吗?谢谢!

2 个答案:

答案 0 :(得分:0)

重组代码

不幸的是,由于行为的运作方式 - 完全按照要求解决这一点并非无足轻重。

你可以这样做:

$Clients = $this->paginate();

// extract category ids in the results
$categoryIds = array_unique(Hash::extract($Clients, '{n}.Category.{n}.id'));

$categories = $this->Client->Category->find('all', array(
    'conditions' => array(
        'Category.id' => $categoryIds
    )
));

// generate a category-id indexed array of categories
$categories = Hash::combine($categories, '{n}.Category.id', '{n}.Category');

// replace the untranslated category entries with translated category data
foreach($Clients as &$client) {
    foreach($client['Category'] as &$cat) {
        $id = $cat['id'];
        $cat = $categories[$id];
    }
}

此示例显示为伪控制器代码 - 您还可以考虑将其放在Client afterFind方法或custom finder中。

答案 1 :(得分:0)

感谢您的帮助。 我找到了解决方案:

我将下面的代码添加到AppModel-> afterFind中,它可以正常工作

public function afterFind($results, $primary = false) {    
if(!empty($this->hasAndBelongsToMany)) {
    foreach($this->hasAndBelongsToMany as $model => $settings) {
        if(isset($this->{$model}->actsAs['Translate'])) {
            if(!empty($results[0][$model])) {
                foreach($results as $k => $v){
                    foreach($results[$k][$model] as $row => $result) {
                        $supplement = $this->{$model}->find('first', array(
                            'conditions' => array(
                                $model .'.id' => $result['id']),
                            'fields' => $this->{$model}->actsAs['Translate'],
                            'recursive' => -1));

                        if(!empty($supplement)) {
                            $results[$k][$model][$row] = array_merge($results[$k][$model][$row], array_diff($supplement[$model], $result));
                        }
                    }
                }// end foreach k=>v
            }
        }
    }
}

return $results;

}