2014-07-01 3 views
-2

Давайте посмотрим, мой архитектор:Доктрина, MVC, Symfony: где я могу использовать Доктрину? Могу ли я использовать его в контроллере?

Модель:

// links table: (ID, LINKNAME) 
Class Link extends Link_base 
{ 
} 

Контроллер:

public function index() 
{ 
    $this->links = new Doctrine - here I build the query, SELECT, ORDER BY, etc 
} 

в этом примере, модель может быть, остаются пустыми (без серьезной логики), все, что мне нужно, это выберите с заказом. Я не уверен, что могу использовать Doctrine в контроллере, хотя я должен переделать его вот так?

Class Link extends Link_base 
{ 
    public function getLinks() 
    { 
     return new Doctrine - here I build the query, SELECT, ORDER BY, etc; 
    } 
} 

Контроллер:

public function index() 
{ 
    $this->links = Links::getLinks(); 
} 

Я не уверен, какой путь, кажется, в порядке. Конечно, при выборе потребностей более сложное форматирование todo-s, оно идет к модели или помощнику, но я чувствую, что просто создал новый (ненужный) слой. Этот getLinks() используется только один раз. Другими словами: Доктрина может использоваться только в модели, или же она может использоваться и в контроллерах?

+0

май - да; должен - ** НЕТ ** –

+0

Можете ли вы подтвердить это с помощью примера или источника? –

+0

Doctrine2 - это структура абстракции настойчивости (реализация [data mapper] (http://martinfowler.com/eaaCatalog/dataMapper.html)) и никогда не должна подвергаться воздействию уровня сохранения. Вместо этого он должен использоваться в службах для хранения и извлечения данных из объектов домена (в пределах уровня модели). –

ответ

2

Ваших лица (или модель, если вы предпочитаете это имя) должен не знать как они сохраняются в/извлечены из базы данных. Они должны быть просто объектами PHP, содержащими только ряд свойств (соответствующих столбцам базы данных), а также их получатели и сеттеры.

(Если вы заинтересованы, читайте немного о single responsibility principle, которая гласит, что каждый класс должен иметь один и только один ответственность. Если вы сделаете свои объекты и отвечает за хранение данных и зная, как сохранить эти данные в база данных, у вас будет больше шансов внедряющих ошибок, когда одна из тех вещей изменений)

вы можете получить объекты внутри контроллера:.

<?php 

namespace Your\Bundle\Controller; 

use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class LinkController extends Controller 
{ 
    public function fooAction() 
    { 
     $links = $this->getDoctrine() 
      ->getRepository('YourBundle:Link') 
      ->findAll(); 

     // do something with the result, like passing it to a template 
    } 
} 

Однако вам может понадобиться более сложный запрос (который включает сортировку и фильтрацию), и вам может потребоваться выполнить этот запрос с нескольких контроллеров. В этом случае вы не хотите дублировать эту логику на несколько контроллеров, вы хотите сохранить эту логику в одном центральном месте.

Чтобы сделать это, создайте хранилище:

<?php 

namespace Your\Bundle\Repository; 

use Doctrine\ORM\EntityRepository; 

class LinkRepository extends EntityRepository 
{ 
    public function findAllOrderedByName() 
    { 
     return $this->getEntityManager() 
      ->createQuery(
       'SELECT l FROM YourBundle:Link l ORDER BY l.name ASC' 
      ) 
      ->getResult(); 
    } 
} 

И добавить класс хранилища для вашего отображения:

Your\Bundle\Entity\Link: 
    type: entity 
    repositoryClass: Your\Bundle\Repository\LinkRepository 

(проверьте Symfony's documentation about custom repositories, если вы используете XML или аннотации вместо YAML)

Теперь в вашем контроллере вы можете просто обновить свой метод fooAction, чтобы он использовал ваш метод репозитория:

public function fooAction() 
{ 
    $links = $this->getDoctrine() 
     ->getRepository('YourBundle:Link') 
     ->findAllOrderedByName(); 
} 

Для получения дополнительной информации документация Symfony включает в себя great article about Doctrine. Если вы еще этого не сделали, я бы определенно рекомендовал его прочитать.

+0

Красиво объяснено. Это напоминает полезность репозиториев. –

Смежные вопросы