在一个项目中,我有两个模型,产品和包。包可以看作是产品的容器,为了在包中定义项目,我创建了一个模型PackageItem (它基本上是一个产品,所以它使用相同的表)。现在产品(以及PackageItems)都有可翻译的字段,比如标题和描述。
ProductsTable.php包含:
$this->addBehavior('Translate', [
'fields' => ['title', 'description'],
'translationTable' => 'products_translations'
]);
$this->belongsToMany('PackageItems', [
'foreignKey' => 'package_id',
'joinType' => 'LEFT',
'joinTable'=>'products_package_items'
]);
PackageItemsTable包含:
$this->table('products');
$this->addBehavior('Translate', [
'fields' => ['title', 'description'],
'translationTable' => 'products_translations'
]);
$this->belongsTo('Products', [
'foreignKey' => 'package_item_id',
'joinType' => 'LEFT'
]);
使用TranslateBehavior,我可以返回产品上的翻译,但我不知道如何编写查询,我也需要在PackageItems上返回翻译。这是我当前的查询:
$package = $this->Products->find('translations')
->where(['business_id'=>$q['business_id'], 'id'=>$id, 'type'=>'Package'])
->contain([
'PackageItems'=>[
'Prices'=>function($q) {
return $q->where(['product_id'=>$this->product_id]);
}
]
])
->first();
发布于 2016-06-11 13:38:07
你需要两件事
1)设置正确的引用名称
需要将PackageItemsTable
类上的转换行为配置为使用与ProductsTable
类上的行为相同的引用名称(存储在model
列中的值),否则您将永远不会收到任何翻译,因为默认情况下它将查找PackageItems
。
这就是可以使用referenceName
选项的地方。引用名是从类名(而不是别名)派生的,或者是从数据库表名或别名派生的自动表。因此,对于您的ProductsTable
类,它将是Products
。
或者手动设置名称
$this->addBehavior('Translate', [
'fields' => ['title', 'description'],
'translationTable' => 'products_translations',
'referenceName' => 'Products' // there it goes
]);
或者从ProductsTable
上的行为中动态检索它,如
$referenceName = $this->Products
->target()
->behaviors()
->get('Translate')
->config('referenceName');
但是,这需要在为belongsTo
表添加相应的Products
关联之后完成!
2)使用translations
查找器作为容器
您需要配置PackageItems
容器以使用translations
查找器,它非常简单
contain([
'PackageItems' => [
'finder' => 'translations', // there you go
'Prices' => function ($q) {
return $q->where(['product_id' => $this->product_id]);
}
]
])
另请参阅
https://stackoverflow.com/questions/37743537
复制相似问题