所以你有以下层次结构
- 公司拥有众多用户
- 公司拥有众多设施
- 设施有很多 区域
- 区域有很多产品线
- 产品有很多产品线
产品通过关系链接到区域 as manyToMany productLines
您可以为您的 AR 类使用以下代码(但您应该修复名称,因为我对类和表名使用了单数形式):
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();
要获取特定区域的产品内部代码,请在 Product 类中添加以下函数:
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();
希望这可以帮助。