2016-04-18 10 views
0

プロジェクトでは、「カード」を管理する必要があります。 「クライアントカード」と「会員カード」の2種類のカードがあります。 カードはこのアプリケーションのユーザーが注文することができます。Doctrine2 /弁別器の値を照会

これを達成するために、Typeディスクリミネータを使用して抽象的なCardエンティティを作成しました。

/* @ORM\Entity 
* @ORM\Table(name="cards") 
* @ORM\InheritanceType("SINGLE_TABLE") 
* @ORM\DiscriminatorColumn(name="type", type="string") 
* @ORM\DiscriminatorMap({"member"="MemberCard", "client"="ClientCard"}) 
*/ 
abstract class Card 
{ 
    const MEMBER = 'member'; 
    const CLIENT = 'client'; 

    /** 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="IDENTITY") 
    * @ORM\Column(type="integer") 
    */ 
    protected $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="CardsOrder", inversedBy="cards") 
    * @ORM\JoinColumn(name="order_id", referencedColumnName="id", onDelete="CASCADE") 
    */ 
    protected $order; 

    /** 
    * Return the card type 
    * 
    * @return string 
    */ 
    abstract public function getType(); 

    /** 
    * @return mixed 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * @param CardsOrder $order 
    * 
    * @return $this 
    */ 
    public function setOrder(CardsOrder $order) 
    { 
     $this->order = $order; 

     return $this; 
    } 

    /** 
    * @return CardsOrder 
    */ 
    public function getOrder() 
    { 
     return $this->order; 
    } 
} 

MemberCardエンティティ

/** 
* @ORM\Entity 
*/ 
class MemberCard extends Card 
{ 

    /** 
    * @ORM\ManyToOne(targetEntity="Member", inversedBy="cards") 
    * @ORM\JoinColumn(name="member_id", referencedColumnName="id", onDelete="CASCADE") 
    */ 
    protected $member; 

    /** 
    * @param Member $member 
    * 
    * @return $this 
    */ 
    public function setMember(Member $member) 
    { 
     $this->member = $member; 

     return $this; 
    } 

    /** 
    * @return Member 
    */ 
    public function getMember() 
    { 
     return $this->member; 
    } 

    /** 
    * @return string 
    */ 
    public function getType() 
    { 
     return self::MEMBER; 
    } 
} 

/** 
* @ORM\Entity 
*/ 
class ClientCard extends Card 
{ 

    /** 
    * ClientCard - client n-1 relation 
    * 
    * @ORM\ManyToOne(targetEntity="Client", inversedBy="cards") 
    * @ORM\JoinColumn(name="client_id", referencedColumnName="id", onDelete="CASCADE") 
    */ 
    protected $client; 

    /** 
    * @param \Admin\Crm\Entity\Client\Client $client 
    * 
    * @return $this 
    */ 
    public function setClient(Client $client) 
    { 
     $this->client = $client; 

     return $this; 
    } 

    /** 
    * @return Client 
    */ 
    public function getClient() 
    { 
     return $this->client; 
    } 

    /** 
    * @return string 
    */ 
    public function getType() 
    { 
     return self::CLIENT; 
    } 

} 

は今、私はメンバーやクライアントが保留注文したカードを持っている場合、ステータスは、バイナリステータスです(知りたいClientCardエンティティフラグ):

public function findPendingCard($clientOrMember) 
{ 
    // $this->getRepository is the Card repository, injected in a factory 
    $query = $this->getRepository()->createQueryBuilder('c') 
         ->join('c.order', 'o', 'WITH', 'BIT_AND(o.status, :oStatus) > 0') 
         ->where('c INSTANCE OF :memberCardEntity AND c.member = :clientOrMember') 
         ->orWhere('c INSTANCE OF :clientCardEntity AND c.client = :clientOrMember') 
         ->setParameters([ 
          'oStatus'  => CardsOrder::OPEN, 
          'clientOrMember' => $clientOrMember, 
          'memberCardEntity' => MemberCard::class, 
          'clientCardEntity' => ClientCard::class, 
         ]) 
         ->getQuery(); 

     return $query->getOneOrNullResult(); 
    } 

しかし、私はこのエラーを得た:私が間違ってやっている

[Semantical Error] line 0, col 148 near 'member = :clientOrMember)': Error: Class Card has no field or association named member 

任意のアイデアを?

答えて

1

何か間違っていることはあまりありませんが、問題を回避する方法があります。次のようにしてカードの種類を返すことができます。クラスカードの追加で

:クラスMemberCardで

public function getCardType() 
{ 
    return $this->discr; 
} 

は追加:クラスの

protected $discr = 'member'; 

を追加ClientCard:

protected $discr = 'client'; 
+0

geoB @、これは非常に素晴らしいと便利なトリックに感謝を!それは私を助け、エンティティインスタンスをもうチェックする必要はありません。しかし、 'MemberCard :: $ member'や' ClientCard :: $ member'の値をチェックする方法は?この問合せをSQLで書く必要がある場合、SELECT * from cards c JOIN card_orders o ON(c.order_id = o.id)WHERE((c.type = 'member' AND c.member_id =?)OR( '' ctype = 'client' AND c.client_id =?)).... ' – ceadreak

+0

あなたのクエリはどうなりますか(' type' == 'discr'と仮定します)? – geoB

+0

はい、タイプはdiscrです。クエリは正しいですが、 'card'リポジトリを使用してクエリビルダーでこの部分を書く方法が問題です:' c.member_id =? '...' c.client_id =? '' member'と 'client'は抽象的なエンティティ 'Card'から子プロパティの直接プロパティ – ceadreak

関連する問題