CakePHP 3:作为别名的模型上的 TranslateBehavior
CakePHP 3: TranslateBehavior on a model that works as an alias
在一个项目中,我有两个模型,产品和包。包可以看作是产品的容器,为了定义包中的项目,我创建了一个模型 PackageItem(它基本上是一个产品,所以它使用相同的 table)。现在产品(以及 PackageItems)具有 translatable 字段,例如标题和描述。
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 我能够 return 产品的翻译,但我不知道如何编写查询,我还需要 return 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();
你需要两件事
1) 设置正确的参考名称
PackageItemsTable
class 上的翻译行为需要配置为使用相同的引用名称(存储在 model
列中的值)作为ProductsTable
class,否则您将永远不会收到任何翻译,因为它会默认查找 PackageItems
。
这就是 referenceName
选项的用途。参考名称源自 class 名称(不是别名),或者对于自动 tables,来自数据库 table 名称或别名。所以对于你的 ProductsTable
class 它将是 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');
然而,这需要在 为 Products
table!
添加相应的 belongsTo
关联之后完成
2) 使用 translations
收容
查找器
您需要配置 PackageItems
容器才能使用 translations
查找器,这与
一样简单
contain([
'PackageItems' => [
'finder' => 'translations', // there you go
'Prices' => function ($q) {
return $q->where(['product_id' => $this->product_id]);
}
]
])
另见
在一个项目中,我有两个模型,产品和包。包可以看作是产品的容器,为了定义包中的项目,我创建了一个模型 PackageItem(它基本上是一个产品,所以它使用相同的 table)。现在产品(以及 PackageItems)具有 translatable 字段,例如标题和描述。
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 我能够 return 产品的翻译,但我不知道如何编写查询,我还需要 return 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();
你需要两件事
1) 设置正确的参考名称
PackageItemsTable
class 上的翻译行为需要配置为使用相同的引用名称(存储在 model
列中的值)作为ProductsTable
class,否则您将永远不会收到任何翻译,因为它会默认查找 PackageItems
。
这就是 referenceName
选项的用途。参考名称源自 class 名称(不是别名),或者对于自动 tables,来自数据库 table 名称或别名。所以对于你的 ProductsTable
class 它将是 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');
然而,这需要在 为 Products
table!
belongsTo
关联之后完成
2) 使用 translations
收容
查找器
您需要配置 PackageItems
容器才能使用 translations
查找器,这与
contain([
'PackageItems' => [
'finder' => 'translations', // there you go
'Prices' => function ($q) {
return $q->where(['product_id' => $this->product_id]);
}
]
])