2016-08-08 12 views
0

ich Fragen habe ein Feld aus einer Tabelle Tasten mit zwei ausländischen zu bekommen.Yii2 Relations ein Feld mit zwei Fremdschlüssel zu bekommen

erklärt die Beziehungen der Verwendung Tabellen unten.

  • Benutzertabelle hasMany Companies (company_id).
  • Firma Tabelle hat company_id.
  • Einrichtungen hasOne company_id (Basierend auf der Benutzerinstanz).
  • Gebiet hasMany Facilites (facility_id).

Der angemeldete Benutzer wird Bereiche haben, die mit facilities_id in Beziehung stehen, was wiederum mit company_id zusammenhängt.

Ich habe jetzt ein

  • Produktlinien hasMany Produkte (product_id).

Der Benutzer sollte auf die Bereiche verwandte Produkte anzuzeigen.

  • Produktlinien hasMany Areas (area_id).
  • Produktlinien haben ein Feld namens internal_code.

Das Produktmodell hat eine Beziehung zu Produktlinien auf der Basis von products_id.

Ich möchte auf der Basis von product_id diesen internen Code angezeigt werden, die zu den spezifischen Bereichen gehören.

Mein Code wie jetzt, die nicht funktioniert: Modell

In meinem Produkt.

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

Meiner Ansicht Datei:

[ 
     'label' => 'Internal Code', 
     'format' => 'raw', 

     'value' => function ($data) { 
      foreach ($data->productlines as $intCode) 
      return $intCode->internal_code; 
     } 

Ich verstehe nicht, wie diese Beziehungen zu verknüpfen. Suche nach Hilfe. Dank

Liste der Tabellen:

  • Benutzer (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)
  • Produktlinien (primaryKey - productlines_id, foreignKey - product_id und area_id)
  • Produkt (primaryKey - product_id).

Mein erwartetes Ergebnis:

enter image description here

In der obigen Tabelle können Sie sehen, area_id 47 hat zwei product_id sind (1 und 3). und der interne Code für sie ist anders. Ich möchte, dass sie beide internen Codes ab sofort zurückgeben, ich kann nur einen internen Code bekommen.

+0

Es ist nicht klar, welche Entitäten Sie haben und wie sie verknüpft sind.Können Sie eine vollständige Liste von Tabellen mit Primärschlüsseln und Fremdschlüsseln bereitstellen (nur Namen reichen aus)? Und zeigen Sie bitte ein Beispiel für das erwartete Ergebnis – oakymax

+0

@MaximKorshunov Ich habe die Tabellennamen und Beziehungen hinzugefügt .. –

Antwort

1

So haben Sie Hierarchie nach

  • Firma hasMany Benutzer
  • Firma hasMany Einrichtungen
  • Einrichtung hasMany Bereiche
  • Gebiet hasMany Produktlinien
  • Produkt hasMany Produktlinien

Produkte werden als ManyToManyüberproductLines Beziehung

auf Bereiche verknüpft Sie folgenden Code für Ihre AR-Klassen verwenden können (aber Sie sollten die Namen beheben, weil ich verwendet ein Singular-Formular für Klassen und Tabellennamen):

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

um alle internen Codes für bestimmte Pro zu erhalten Leitung:

$productLines = $product->productLines; 

$internalCodesAsArray = array_map(function(ProductLine $productLine) { 
    return $productLine->internal_code; 
}, $productLines); 

$internalCodesAsString = join(', ', $internalCodesAsArray); 

alle internen Codes für bestimmten Bereich zu erhalten:

$productLines = $product->productLines; 

$internalCodesAsArray = array_map(function(ProductLine $productLine) { 
    return $productLine->internal_code; 
}, $productLines); 

$internalCodesAsString = join(', ', $internalCodesAsArray); 

Das gleiche, wenn Sie Produkte für bestimmten Bereich auflisten möchten - $area->products Beziehung verwenden. Wenn Sie möchten Produkte für bestimmten Bereich zählen zu bekommen, dann rufen $area->getProducts()->count();

Um internen Codes des Produktes für bestimmte Bereich Add folgenden Funktion in Produktklasse zu erhalten:

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

und verwenden Sie es in Ihrem Controller als $currentProduct->getInternalCodes($currentArea)

Fügen Sie keine benutzerdefinierten Filter zu Funktionen hinzu, die Relationen definieren. Wenn Sie für bestimmte Artikel erhalten Liste der Einrichtungen wollen und filtern sie durch Unternehmen der aktuellen Benutzer dann implementieren besser als Zusatzfunktion:

public class Product 
{ 
    ... 

    public function getFacilitiesByCompany(Company $company) 
    { 
     return $product->getFacilities() 
      ->where(['company_id' => $company->company_id]); 
    } 
} 

und es verwenden, wie folgt

$product->getFacilitiesByCompany(Yii::$app->user->identity->company)->all(); 

Hoffnung, das hilft.

+0

Es bietet mir die gleiche vorherige Antwort .. Keine Änderungen .. –

+0

@MohanPrasad Dann habe ich wahrscheinlich nicht Ihre Frage bekommen. – oakymax

+0

alle Ihre Beziehungen sind vollkommen intakt .. Es ist nur die Ansicht Seitencode internen Code zu bekommen .. Ich habe verschiedene Bereiche. Basierend auf diesen Bereichen bekomme ich die Produkte auf meiner Produktseite. verschiedene Bereiche können dieselben Produkte haben. Hier haben die gleichen Produkte unterschiedliche interne Codes. Ich möchte den internen Code entsprechend den Bereichen anzeigen. –

Verwandte Themen