2017-01-23 2 views
0

私は2つのエンティティ、InvoiceとInvoiceItemをymlで次のように定義しています。奇妙な教義の実体の動作

Invoice.orm.yml

AppBundle\Entity\Invoice: 
type: entity 
table: invoices 
repositoryClass: AppBundle\Repository\InvoiceRepository 
fields: 
    id: 
     id: true 
     type: integer 
     generator: 
      strategy: AUTO 
    ...... 

oneToMany: 
    items: 
    targetEntity: InvoiceItem 
    mappedBy: invoice 
    deductions: 
    targetEntity: InvoiceDeduction 
    mappedBy: invoice 
    payments: 
    targetEntity: InvoicePayment 
    mappedBy: invoice 

InvoiceItem.orm.yml

AppBundle\Entity\InvoiceItem: 
type: entity 
table: invoice_items 
repositoryClass: AppBundle\Repository\InvoiceItemRepository 
fields: 
    id: 
     id: true 
     type: integer 
     generator: 
      strategy: AUTO 
.... 
manyToOne: 
    invoice: 
    targetEntity: Invoice 
    inversedBy: items 
    joinColumn: 
     invoice_id: 
     referencedColumnName: id 
     onDelete: CASCADE 

マイコントローラは、請求書の詳細を受信し

public function createInvoiceAction(Request $request) 
{ 
    .... 
    $invoice = new Invoice(); 
    $invoice->setReference($ref); 
    $invoice->setInvoiceDate(\DateTime::createFromFormat('d/m/Y',$request->query->get('invoiceDate'))); 
    $invoice->setDescription($request->query->get('summary')); 
    $invoice->setAttn($request->query->get('att')); 
    $invoice->setIsVatable($request->query->get('vattable') == 'true' ? 1 : 0); 
    $invoice->setAdditionalInstructions($request->query->get('additional')); 
    $invoice->setJob($job); 
    $invoice->setCurrency($request->query->get('currency')); 
    $invoice->setGeneratedBy($createdBy); 
    $invoice->setFile($filename); 
    $job->setStatus('Invoiced'); 
    $em->persist($invoice); 
    $em->persist($job); 
    $em->flush(); 

    $items = $request->query->get('items'); 
    for($i=0;$i<count($items);$i++) 
    { 
     if($items[$i]['description']!= '' && $items[$i]['amount'] != '') 
     { 
     $item = new InvoiceItem(); 
     $item->setDescription($items[$i]['description']); 
     $item->setAmount($items[$i]['amount']); 
     $item->setInvoice($invoice); 
     $em->persist($item); 
     $em->flush(); 
     } 
    } 

    $deductions = $request->query->get('deductions'); 
    for($i=0;$i<count($deductions);$i++) 
    { 
     if($deductions[$i]['description'] != '' && $deductions[$i]['value'] != '') 
     { 
     $deduction = new InvoiceDeduction(); 
     $deduction->setDescription($deductions[$i]['description']); 
     $deduction->setValue($deductions[$i]['value']); 
     $deduction->setIsPercentage($deductions[$i]['isPercentage'] == 'true' ? 1 : 0); 
     $deduction->setInvoice($invoice); 
     $em->persist($deduction); 
     $em->flush(); 
     } 
    } 

    $html = $this->renderView('AppBundle:Default:invoice.html.twig', array('invoice' => $invoice)); 

    return new Response(
     $html 
    ); 
} 

invoice.html以下に示すように要素を保存.twigは、明細や控除を含む請求書の詳細をレンダリングします。

..... 

{% for item in invoice.items %} 
    <tr> 
     <td>{{ loop.index }}</td> 
     <td>{{ item.description }}</td> 
     <td>{{ item.amount|number_format(0, '', ',') }}</td> 
    </tr> 
{% endfor %} 
..... 

私がいる課題は、テンプレートに送ら$請求書オブジェクトをコレクションすることになっている商品や控除を持っていないことです。私はデータベースをチェックして、アイテムと控除がそれぞれのテーブルに保持されていることを確認できるので、なぜ表にinvoice.itemsまたはinvoice.deductionsがないのかわかりません。

私はすべてのInvoiceItemオブジェクトの作成後に、永続トランザクションが完了する前にテンプレートがレンダリングされた可能性があると考えていましたが、これも役に立たなかったと思います。

+0

請求書明細データベーステーブルを再度確認してください。私はinvoice_idがNULLだと思う? – Cerad

答えて

0

UPDATE:

私が発見してきた少なくとも1つの他のエラーがjoinColumnの下で定義されているonDeleteオプションです。それは次のようになります。

manyToOne: 
    invoice: 
    targetEntity: Invoice 
    inversedBy: items 
    joinColumn: 
     invoice_id: 
     referencedColumnName: id 
    onDelete: CASCADE 

--------

ビューがcreateInvoiceAction中にレンダリングされる場合にのみ、この問題が発生した場合、問題は「あなたはドンので、ということかもしれません実際にInvoiceItemをaddItem()のようなメソッドを介してInvoiceオブジェクトに追加します(命名はインボイスエンティティのリレーションに名前を付ける方法によって異なります)。これらのアイテムは次回のInvoiceエンティティにのみ存在する可能性があります請求書を照会するのは、各明細の請求書を設定していても、それらのエンティティが今作成されていれば、doctrineはプロを使用してそれらを取得できない可能性があるからですxyクラス。だから、解決策は単純次のようになります。ただし、請求書に項目を追加すると、そのメソッド内

public function addItem(InvoiceItem $item) 
{ 
    $item->setInvoice($this); 
    $this->items[] = $item; 

    return $this; 
} 

を与えられた項目の請求書を設定し、ロジックを追加することを忘れないでください請求書エンティティにAddItemメソッドを使用します次に問題が解決されない場合は、オブジェクトが実際にgetterメソッドを含んでいるかどうかをチェックし、単にパブリックプロパティを使用してアイテムにアクセスしようとしていないかどうかを確認することをお勧めします。つまり、請求書クラスの内部でitemsという名前のプロパティをprivateとして定義する必要があります。また、アイテムを取得するgetItems()メソッドが必要です。 doctrineで使用するオブジェクトには、プロキシクラスを使用するメソッド内のロジックをオーバーライドして、データベースからInvoiceItemを取得するクエリを送信するコードを追加するため、これらのメソッドが必要です。それらをオブジェクトのプライベートプロパティの内部に配置し、クラス内でゲッターコードを実行します。これらのメソッドがなければ、プライベートプロパティは空にとどまります。なぜなら、doctrineがあなたのデータベースからそれらを取得する他の方法はないからです( "EAGER"をフェッチしない限り)。

+0

ありがとうございました。私はすでに最初の提案を試みたが、うまくいかなかった。 この動作は本当に奇妙で、コントローラレベルでは問題があるようですが、Sonata Adminを使用すると、getterメソッドを使用して請求書アイテムにアクセスできますが、コントローラでは同じことはできません。 –

+0

InvoiceItem.ymlファイルのインデントにエラーが発生しました。カスケード削除をjoinColumnの1つとして定義しています。私はそれに応じて私の答えを更新しました。お役に立てれば :) – grssn