Yii2 Relations to get a field using two foreign keys -


i have issues field table using 2 foreign keys.

explained relations of use tables below.

  • user table hasmany companies(company_id).
  • comapny table has company_id.
  • facilities hasone company_id(based on user instance).
  • area hasmany facilites(facility_id).

the logged on user have areas related facilities_id in turn related company_id.

i have a

  • productlines hasmany products(product_id).

the user should display products related areas.

  • productlines hasmany areas(area_id).
  • product lines has field called internal_code.

product model has relation productlines on basis of products_id.

i want display internal code on basis of product_id belongs specific areas.

my code of not working :

in product model.

    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']); } 

in view file:

  [         'label' => 'internal code',         'format' => 'raw',          'value' => function ($data) {             foreach ($data->productlines $intcode)            return $intcode->internal_code;         }  

i don't understand how link these relations. looking help. thanks

list of tables:

  • users (primarykey - users_id, foreign_key- comapny_id)
  • company(primarykey - company_id)
  • facility(primarykey - facility_id, foreignkey- company_id)
  • areas(primarykey - area_id, foreignkey- facility_id)
  • productlines(primarykey - productlines_id, foreignkey - product_id , area_id)
  • product (primarykey - product_id).

my expected result:

enter image description here

in above table can see area_id 47 has 2 product_id's (1 , 3). , internal code them different. want them return both internal codes of can 1 internal code.

so have following hierarchy

  • company hasmany users
  • company hasmany facilities
  • facility hasmany areas
  • area hasmany productlines
  • product hasmany productlines

products linked areas manytomany via productlines relation

you can use following code ar classes (but should fix names, because used singular form classes , table names):

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');     } } 

to internal codes given product:

$productlines = $product->productlines;  $internalcodesasarray = array_map(function(productline $productline) {     return $productline->internal_code; }, $productlines);  $internalcodesasstring = join(', ', $internalcodesasarray); 

to internal codes given area:

$productlines = $product->productlines;  $internalcodesasarray = array_map(function(productline $productline) {     return $productline->internal_code; }, $productlines);  $internalcodesasstring = join(', ', $internalcodesasarray); 

the same if want list products given area -- use $area->products relation. if want products count given area, call $area->getproducts()->count();

to internal codes of product specific area add following function product 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()); } 

and use in controller $currentproduct->getinternalcodes($currentarea)

do not add custom filters functions define relations. if want list of facilities given product , filter them company of current user better implement additional function:

public class product  {     ...      public function getfacilitiesbycompany(company $company)     {         return $product->getfacilities()             ->where(['company_id' => $company->company_id]);     } } 

and use follows

$product->getfacilitiesbycompany(yii::$app->user->identity->company)->all(); 

hope helps.


Comments

Popular posts from this blog

Spring Boot + JPA + Hibernate: Unable to locate persister -

go - Golang: panic: runtime error: invalid memory address or nil pointer dereference using bufio.Scanner -

c - double free or corruption (fasttop) -