2016-08-25 5 views
1

Ich habe eine AutoComplete mit Modellnamen im folgenden Code arbeiten. Ich habe Schwierigkeiten, es zu erweitern, um die Autovervollständigung die Markennamen einschließen zu lassen. Zum Beispiel, wenn es eine Marke von Sony mit den Modellen ST1 und ST2 gibt, würde ich gerne in der Lage sein, Sony zu geben und zwei Reihen zu bekommen - Sony ST1 und Sony ST2, aber wenn ich ST1 eintrage, würde ich gerne einen haben Reihe - Sony ST1.Erweitern eines FilteringSelect/AutoComplete mit Symfony und Doctrine

Controller-Code

/** 
* @View() 
*/ 
public function getModelsAction(Request $request) 
{ 
    $this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!'); 

    $modelName = str_replace('*', '%', $request->get('name')); 

    $em = $this->getDoctrine()->getManager(); 

    $queryBuilder = $em->createQueryBuilder() 
      ->select('m') 
      ->from('AppBundle:Model', 'm'); 

    $queryBuilder->where(
      $queryBuilder->expr()->like('m.name', '?1') 
    ); 
    $queryBuilder->setParameter(1, $modelName); 

    $query = $queryBuilder->getQuery(); 
    $modelCollection = $query->getResult(); 
    $data = []; 

    foreach($modelCollection as $m) 
    { 
     $item = [ 
      'id' => $m->getId(), 
      'name' => $m->getName(), 
     ]; 

     $data[] = $item; 
    } 
    return $data; 
} 

Verbindung zwischen Marken und Modelle (Anmerkung)

/** 
* @var ArrayCollection $brands 
* @ORM\ManyToMany(targetEntity="Model", cascade={"persist"}) 
* @ORM\JoinTable(name="brand_model", 
*  joinColumns={@ORM\JoinColumn(name="brand_id", referencedColumnName="id", onDelete="CASCADE")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="model_id", referencedColumnName="id", unique=true, nullable=false)} 
*  ) 
*/ 
protected $models = null; 

Datenbank

Marke

dev=# \d brand 
            Table "public.brand" 
    Column |    Type    |     Modifiers     
------------+--------------------------------+------------------------------------------- 
id   | integer      | not null 
name  | character varying(64)   | default NULL::character varying 
active  | boolean      | not null 
deleted_at | timestamp(0) without time zone | default NULL::timestamp without time zone 
comment | character varying(64)   | default NULL::character varying 
Indexes: 
    "brand_pkey" PRIMARY KEY, btree (id) 
Referenced by: 
    TABLE "manufacturer_brand" CONSTRAINT "fk_170c6d4844f5d008" FOREIGN KEY (brand_id) REFERENCES brand(id) 
    TABLE "brand_model" CONSTRAINT "fk_8c6cbbce44f5d008" FOREIGN KEY (brand_id) REFERENCES brand(id) ON DELETE CASCADE 

Modell

dev=# \d model 
            Table "public.model" 
    Column |    Type    |     Modifiers     
------------+--------------------------------+------------------------------------------- 
id   | integer      | not null 
name  | character varying(64)   | default NULL::character varying 
comment | character varying(64)   | default NULL::character varying 
active  | boolean      | not null 
deleted_at | timestamp(0) without time zone | default NULL::timestamp without time zone 
Indexes: 
    "model_pkey" PRIMARY KEY, btree (id) 
Referenced by: 
    TABLE "brand_model" CONSTRAINT "fk_8c6cbbce7975b7e7" FOREIGN KEY (model_id) REFERENCES model(id) 

brand_model

dev=# \d brand_model 
    Table "public.brand_model" 
    Column | Type | Modifiers 
----------+---------+----------- 
brand_id | integer | not null 
model_id | integer | not null 
Indexes: 
    "brand_model_pkey" PRIMARY KEY, btree (brand_id, model_id) 
    "uniq_8c6cbbce7975b7e7" UNIQUE, btree (model_id) 
    "idx_8c6cbbce44f5d008" btree (brand_id) 
Foreign-key constraints: 
    "fk_8c6cbbce44f5d008" FOREIGN KEY (brand_id) REFERENCES brand(id) ON DELETE CASCADE 
    "fk_8c6cbbce7975b7e7" FOREIGN KEY (model_id) REFERENCES model(id) 

Antwort

1

Sie können Ihre Query Builder ändern:

$queryBuilder = $em->createQueryBuilder() 
    ->select('m.id, CONCAT(CONCAT(b.name, ' '), m.name)') 
    ->from('AppBundle:Model', 'm') 
    ->innerJoin('m.brands', 'b') 
    ->where("CONCAT(CONCAT(b.name, ' '), m.name)' LIKE :brand_model") 
    ->setParameter('brand_model', $brandModel) 
; 

Stellen Sie sicher, dass die andere Seite des many-to-many-Beziehung auf Model Einheit definiert:

class Model 
{ 
    // ... 
    /** 
    * @ManyToMany(targetEntity="Brand", mappedBy="models") 
    */ 
    private $brands; 
} 

Und jetzt Ihr Controller kleine dank der definierten Parameter im ->select(...) Ausdruck (keine Notwendigkeit für ein foreach wird Doctrine es für Sie tun):

public function getModelsAction(Request $request) 
{ 
    // ... 
    // $queryBuilder = ... 

    $data = $queryBuilder->getQuery()->getResult(); 

    return $data; 
} 

Bitte beachte, dass ich durch die Art und Weise Ihre PHP-Programmierung Stil geändert PSR Coding-Standards zu entsprechen.

Verwandte Themen