2012-07-13 29 views
5

Tôi đã thiết lập một gói có đối tượng thử nghiệm chứa một số đối tượng testQuestion mỗi câu hỏi và câu trả lời đã cho (hoặc 0 nếu không có câu trả lời)). Từ twig tôi muốn có thể lấy thông tin từ đối tượng thử nghiệm để nói có bao nhiêu câu hỏi và có bao nhiêu câu trả lời.Symfony2/Doctrine Làm thế nào để lưu trữ số lượng các đối tượng liên quan trong một thực thể

Tôi đã tạo một truy vấn để kéo nó ra khỏi db và trong thực thể kiểm tra, tôi đã tạo 2 thuộc tính mới để lưu trữ số lượng câu hỏi và số được trả lời. Tôi đã tạo ra một TestRepository bên trong mà truy vấn cư trú. Đối tượng Test kiểm tra xem đối tượng có đặt giá trị không và không tải nó khi cần thiết vì tôi sẽ không cần thông tin này.

Tuy nhiên, tôi bị kẹt về cách liên kết mã vùng chứa với đối tượng thử nghiệm, cả hai để gọi hàm repo và chức năng repo để lưu các giá trị cho đối tượng Kiểm tra có liên quan.

Acme/Quizbundle/Kiểm tra/test.php

namespace Acme\QuizBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Acme\QuizBundle\Entity\TestRepository; 

/** 
* @ORM\Entity(repositoryClass="Acme\QuizBundle\Entity\TestRepository") 
* @ORM\Table(name="test") 
*/ 
class Test { 
protected $numQuestions = null; 
protected $numQuestionsAnswered = null; 

public function getNumQuestionsAnswered() { 
    if (is_null($this->numQuestionsAnswered)) { 
     $repository = $this->getEntityManager()->getRepository('\AcmeQuizBundle\Test'); 
     $values = $repository->calculateNumQuestions(); 
    } 
    return $this->numQuestionsAnswered; 
} 

Acme/Quizbundle/Kiểm tra/TestRepository.php (Có một phương pháp phù hợp cho getNumQuestions())

namespace Acme\QuizBundle\Entity; 

use Doctrine\ORM\EntityRepository; 

class TestRepository extends EntityRepository { 

private function calculateNumQuestions() { 

    $qb = $this->getEntityManager() 
       ->createQueryBuilder(); 

    $query = $this->getEntityManager()->createQueryBuilder() 
         ->select('COUNT(id)') 
      ->from('testquestion', 'tq') 
      ->where('tq.test_id = :id') 
      ->setParameter('id', $this->getId()) 
      ->getQuery(); 

    $result = $query->getSingleScalarResult(); 
    var_dump($result); 
    } 

Trả lời

12

Có một số các mẫu khác nhau mà bạn có thể sử dụng để đạt được kết quả này, cách đơn giản nhất là chỉ cần sử dụng aggregate field. Điều này lưu trữ thông tin sau khi nó được sửa đổi, thay vì tính toán nó mỗi khi cần.

Giải pháp thay thế là tạo liên kết một-nhiều giữa kho lưu trữ Kiểm tra và Kiểm tra câu hỏi của bạn (giả sử không có sẵn), sau đó trong mẫu ghép bạn chỉ có thể sử dụng {{ testEntity.questionsAnswered.count() }} - thậm chí bạn có thể nói với Doctrine để thực hiện điều này là "extra-lazy" association để nó sử dụng COUNT câu lệnh SQL để tìm kiếm xem có bao nhiêu câu hỏi được trả lời (theo mặc định nó thực sự tìm nạp các thực thể câu hỏi khi bạn cố gắng liệt kê liên kết).

Cuối cùng, có phương pháp mà tôi không khuyên bạn nên đánh giá cao, nhưng có thể được yêu cầu tùy thuộc vào tình huống của bạn. Tương tự như cách bạn sử dụng trong câu hỏi, bạn lấy số câu hỏi trong kho lưu trữ, nhưng để tiếp tục với phương thức Model đơn giản của Symfony, bạn không khởi động truy vấn từ bên trong thực thể (vì thực thể không bao giờ có thông tin về người quản lý thực thể/kho lưu trữ). Thay vào đó, bạn có thể sử dụng DocTrine EventListener để được thông báo bất cứ khi nào một thực thể Test của bạn được tải (xem here, sử dụng sự kiện postLoad), sau đó gọi phương thức kho lưu trữ của bạn và đặt nó trên thực thể từ đó.

+0

Cảm ơn, điều đó thực sự hữu ích –

+0

Hãy coi chừng 1 Với các liên kết cực kỳ lười biếng, bạn phải sử dụng 'Bộ sưu tập # count()' gọi ** thay vì được xây dựng trong cành ** 'lenght'. ** Cách đúng sẽ sử dụng SQL COUNT: ** '{{testEntity.questionsAnswered.count}}' ('| length' sẽ khiến tìm nạp các hàng trong bộ nhớ!) –

+0

Cảm ơn bạn đã sửa @Sanya_Zol, cập nhật câu trả lời cho phù hợp –

Các vấn đề liên quan