Yii2 Relations 使用两个外键获取字段
Yii2 Relations to get a field using two foreign keys
我在使用两个外键从 table 获取字段时遇到问题。
下面解释了table的使用关系。
- 用户table有许多家公司(company_id)。
- 公司 table 有 company_id.
- 设施hasOneCompany_id(基于用户实例)。
- 区域有许多个设施(facility_id)。
登录用户将拥有与 facilities_id 相关的区域,而 facilities_id 又与 company_id 相关。
我现在有一个
- 产品线有许多个产品(product_id)。
用户应该展示与区域相关的产品。
- 产品线有许多个领域(area_id)。
- 产品线有一个名为 internal_code 的字段。
产品型号与产品线的关系基于products_id。
我想在属于特定地区的product_id的基础上显示这个内码
我的代码目前无法正常工作:
在我的产品模型中。
public function getFacility()
{
return $this->hasMany(Facility::className(),['facility_id' => 'facility_id'])->viaTable('sim_users',['company_id'=> Yii::$app->user->identity->company_id]);
}
public function getArea()
{
return $this->hasMany(Area::className(),['area_id'=>'area_id'])->viaTable('sim_facility',['facility_id'=> 'facility_id' ]);
}
public function getProductlines()
{
return $this->hasMany(Productlines::className(), ['product_id' => 'product_id'])->viaTable('sim_productlines',['product_id' => 'product_id']);
}
在我的视图文件中:
[
'label' => 'Internal Code',
'format' => 'raw',
'value' => function ($data) {
foreach ($data->productlines as $intCode)
return $intCode->internal_code;
}
我不明白如何 link 这些关系。寻求帮助。谢谢
表格列表:
- 用户(主键 - users_id、foreign_key- comapny_id)
- 公司(主键 - company_id)
- 设施(主键 - facility_id,外键 - company_id)
- 区域(主键 - area_id,外键 - facility_id)
- 产品线(主键 - productlines_id,外键 - product_id 和 area_id)
- 产品(主键 - product_id)。
我的预期结果:
在上面的 table 你可以看到 area_id 47 有两个 product_id(1 和 3)。并且它们的内部代码是不同的。我要他们 return 两个内部代码,现在我只能得到一个内部代码。
所以你有以下层次结构
- 公司有很多个用户
- 公司有许多个设施
- 设施有许多个区域
- 地区有许多产品线
- 产品有许多产品线
产品链接到区域的方式为 manyToMany via productLines
关系
您可以为您的 AR classes 使用以下代码(但您应该修复名称,因为我对 classes 和 table 名称使用了单数形式):
public class User extends ActiveRecord
{
public function getCompany()
{
retrun $this->hasOne(Company::className(), ['company_id' => 'company_id']);
}
}
public class Company extends ActiveRecord
{
public function getUsers()
{
retrun $this->hasMany(User::className(), ['company_id' => 'company_id']);
}
public function getFacilities()
{
retrun $this->hasMany(Facility::className(), ['company_id' => 'company_id']);
}
}
public class Facility extends ActiveRecord
{
public function getCompany()
{
retrun $this->hasOne(Company::className(), ['company_id' => 'company_id']);
}
public function getAreas()
{
retrun $this->hasMany(Area::className(), ['facility_id' => 'facility_id']);
}
}
public class Area extends ActiveRecord
{
public function getFacility()
{
retrun $this->hasOne(Facility::className(), ['facility_id' => 'facility_id']);
}
public function getProductLines()
{
retrun $this->hasMany(ProductLine::className(), ['area_id' => 'area_id']);
}
public function getProducts()
{
retrun $this->hasMany(Product::className(), ['product_id' => 'product_id'])
->via('productLines');
}
}
/**
* @property $internal_code
*/
public class ProductLine extends ActiveRecord
{
public function getArea()
{
retrun $this->hasOne(Area::className(), ['area_id' => 'area_id']);
}
public function getProducts()
{
retrun $this->hasMany(Product::className(), ['product_id' => 'product_id']);
}
}
public class Product extends ActiveRecord
{
public function getProductLines()
{
retrun $this->hasMany(ProductLine::className(), ['product_id' => 'product_id']);
}
public function getAreas()
{
retrun $this->hasMany(Area::className(), ['area_id' => 'area_id'])
->via('productLines');
}
public function getFacilites()
{
retrun $this->hasMany(Facility::className(), ['facility_id' => 'facility_id'])
->via('areas');
}
}
获取给定产品的所有内部代码:
$productLines = $product->productLines;
$internalCodesAsArray = array_map(function(ProductLine $productLine) {
return $productLine->internal_code;
}, $productLines);
$internalCodesAsString = join(', ', $internalCodesAsArray);
获取给定区域的所有内部代码:
$productLines = $product->productLines;
$internalCodesAsArray = array_map(function(ProductLine $productLine) {
return $productLine->internal_code;
}, $productLines);
$internalCodesAsString = join(', ', $internalCodesAsArray);
如果您想列出给定区域的产品,同样如此——使用 $area->products
关系。如果你想获得给定区域的产品数量,请调用 $area->getProducts()->count();
获取特定区域产品的内部代码 在产品中添加以下功能 class:
public function getInternalCodes(Area $area = null)
{
$query = $this->getProductLines();
if (!empty($area)) {
$query->where(['area_id' => $area->area_id]);
}
return array_map(function (ProductLine $productLine) {
return $productLine->internal_code;
}, $query->all());
}
并在您的控制器中将其用作 $currentProduct->getInternalCodes($currentArea)
不要将自定义过滤器添加到定义关系的函数中。如果您想获取给定产品的设施列表并按当前用户的公司过滤它们,那么最好将其作为附加功能实现:
public class Product
{
...
public function getFacilitiesByCompany(Company $company)
{
return $product->getFacilities()
->where(['company_id' => $company->company_id]);
}
}
并按如下方式使用
$product->getFacilitiesByCompany(Yii::$app->user->identity->company)->all();
希望对您有所帮助。
我在使用两个外键从 table 获取字段时遇到问题。
下面解释了table的使用关系。
- 用户table有许多家公司(company_id)。
- 公司 table 有 company_id.
- 设施hasOneCompany_id(基于用户实例)。
- 区域有许多个设施(facility_id)。
登录用户将拥有与 facilities_id 相关的区域,而 facilities_id 又与 company_id 相关。
我现在有一个
- 产品线有许多个产品(product_id)。
用户应该展示与区域相关的产品。
- 产品线有许多个领域(area_id)。
- 产品线有一个名为 internal_code 的字段。
产品型号与产品线的关系基于products_id。
我想在属于特定地区的product_id的基础上显示这个内码
我的代码目前无法正常工作:
在我的产品模型中。
public function getFacility()
{
return $this->hasMany(Facility::className(),['facility_id' => 'facility_id'])->viaTable('sim_users',['company_id'=> Yii::$app->user->identity->company_id]);
}
public function getArea()
{
return $this->hasMany(Area::className(),['area_id'=>'area_id'])->viaTable('sim_facility',['facility_id'=> 'facility_id' ]);
}
public function getProductlines()
{
return $this->hasMany(Productlines::className(), ['product_id' => 'product_id'])->viaTable('sim_productlines',['product_id' => 'product_id']);
}
在我的视图文件中:
[
'label' => 'Internal Code',
'format' => 'raw',
'value' => function ($data) {
foreach ($data->productlines as $intCode)
return $intCode->internal_code;
}
我不明白如何 link 这些关系。寻求帮助。谢谢
表格列表:
- 用户(主键 - users_id、foreign_key- comapny_id)
- 公司(主键 - company_id)
- 设施(主键 - facility_id,外键 - company_id)
- 区域(主键 - area_id,外键 - facility_id)
- 产品线(主键 - productlines_id,外键 - product_id 和 area_id)
- 产品(主键 - product_id)。
我的预期结果:
在上面的 table 你可以看到 area_id 47 有两个 product_id(1 和 3)。并且它们的内部代码是不同的。我要他们 return 两个内部代码,现在我只能得到一个内部代码。
所以你有以下层次结构
- 公司有很多个用户
- 公司有许多个设施
- 设施有许多个区域
- 地区有许多产品线
- 产品有许多产品线
产品链接到区域的方式为 manyToMany via productLines
关系
您可以为您的 AR classes 使用以下代码(但您应该修复名称,因为我对 classes 和 table 名称使用了单数形式):
public class User extends ActiveRecord
{
public function getCompany()
{
retrun $this->hasOne(Company::className(), ['company_id' => 'company_id']);
}
}
public class Company extends ActiveRecord
{
public function getUsers()
{
retrun $this->hasMany(User::className(), ['company_id' => 'company_id']);
}
public function getFacilities()
{
retrun $this->hasMany(Facility::className(), ['company_id' => 'company_id']);
}
}
public class Facility extends ActiveRecord
{
public function getCompany()
{
retrun $this->hasOne(Company::className(), ['company_id' => 'company_id']);
}
public function getAreas()
{
retrun $this->hasMany(Area::className(), ['facility_id' => 'facility_id']);
}
}
public class Area extends ActiveRecord
{
public function getFacility()
{
retrun $this->hasOne(Facility::className(), ['facility_id' => 'facility_id']);
}
public function getProductLines()
{
retrun $this->hasMany(ProductLine::className(), ['area_id' => 'area_id']);
}
public function getProducts()
{
retrun $this->hasMany(Product::className(), ['product_id' => 'product_id'])
->via('productLines');
}
}
/**
* @property $internal_code
*/
public class ProductLine extends ActiveRecord
{
public function getArea()
{
retrun $this->hasOne(Area::className(), ['area_id' => 'area_id']);
}
public function getProducts()
{
retrun $this->hasMany(Product::className(), ['product_id' => 'product_id']);
}
}
public class Product extends ActiveRecord
{
public function getProductLines()
{
retrun $this->hasMany(ProductLine::className(), ['product_id' => 'product_id']);
}
public function getAreas()
{
retrun $this->hasMany(Area::className(), ['area_id' => 'area_id'])
->via('productLines');
}
public function getFacilites()
{
retrun $this->hasMany(Facility::className(), ['facility_id' => 'facility_id'])
->via('areas');
}
}
获取给定产品的所有内部代码:
$productLines = $product->productLines;
$internalCodesAsArray = array_map(function(ProductLine $productLine) {
return $productLine->internal_code;
}, $productLines);
$internalCodesAsString = join(', ', $internalCodesAsArray);
获取给定区域的所有内部代码:
$productLines = $product->productLines;
$internalCodesAsArray = array_map(function(ProductLine $productLine) {
return $productLine->internal_code;
}, $productLines);
$internalCodesAsString = join(', ', $internalCodesAsArray);
如果您想列出给定区域的产品,同样如此——使用 $area->products
关系。如果你想获得给定区域的产品数量,请调用 $area->getProducts()->count();
获取特定区域产品的内部代码 在产品中添加以下功能 class:
public function getInternalCodes(Area $area = null)
{
$query = $this->getProductLines();
if (!empty($area)) {
$query->where(['area_id' => $area->area_id]);
}
return array_map(function (ProductLine $productLine) {
return $productLine->internal_code;
}, $query->all());
}
并在您的控制器中将其用作 $currentProduct->getInternalCodes($currentArea)
不要将自定义过滤器添加到定义关系的函数中。如果您想获取给定产品的设施列表并按当前用户的公司过滤它们,那么最好将其作为附加功能实现:
public class Product
{
...
public function getFacilitiesByCompany(Company $company)
{
return $product->getFacilities()
->where(['company_id' => $company->company_id]);
}
}
并按如下方式使用
$product->getFacilitiesByCompany(Yii::$app->user->identity->company)->all();
希望对您有所帮助。