树枝模板中的ManyToOne [英] ManyToOne in a twig template
问题描述
我有以下表格(以及symfony2 / doctrine2 ):
+ ------------------ + + ---------- ---------- +
| forum_sections | | forum_categories |
+ ------------------ + + -------------------- +
|编号├-------- | | id |
|标题| | --------- |栏目|
|位置| |位置|
| created_at | |标题|
+ ------------------ + |描述|
+ -------------------- +
我想将以下html页面存档(不使用项目符号):
- 这是标题(来自forum_sections- > title)
- 论坛1(来自forum_categories-> title)
- 论坛2(来自forum_categories-> title)
- 这是另一个标题(来自forum_sections-> title)
- 论坛3(来自forum_categories-> title)
我做了一些研究关于如何做到这一点。到目前为止,我已经在树枝布局中尝试以下操作:
{%for section in section%}
< h1> ; title< / h1>
{%为类别中的类别%}
bla bla
{%endfor%}
{%endfor%}
在Doctrine2中使用'findAll'查询甚至有可能吗?我尝试了一些组合,但是它们似乎让所有委员会都忽略了这些部分。
我认为问题出在您的实体中,是定义实体之间关系的方式。您需要使用双向映射 http ://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional
I
- 为
ForumSection
实体添加了类别 li>
- 向
ForumSection
实体 - 添加了addCategory(),removeCategory(),getCategories()方法。对
ForumCategory
实体进行inversedBy
批注以完成te关系 - 我使用了getCategories( )方法来获取树枝中该部分的所有类别。
实体;
ForumSection.php
命名空间AppBundle\Entity;
/ **
* @版本0.0.1
* @版权所有(c)2015 Ricardo Jacobs。版权所有。
* @license专有和机密源代码。
* /
使用Doctrine\ORM\映射为ORM;
使用Doctrine\Common\Collections\ArrayCollection;
/ **
* @ ORM\Entity(repositoryClass = AppBundle\Entity\Repositories\Forum)
* @ ORM\HasLifecycleCallbacks
* @ ORM\Table(name = forum_sections)
* /
class ForumSection
{
/ **
* @ ORM\Column(type = integer,name = id)
* @ ORM\Id
* @ ORM\GeneratedValue(strategy = AUTO)
* /
private $ ID;
/ **
* @ ORM\Column(type = string,length = 255,name = title)
* /
private $标题;
/ **
* @ ORM\Column(type = integer,name = position)
* /
private $ position;
/ **
* @ ORM\Column(type = datetime)
* /
private $ created_at;
/ **
* @ ORM\OneToMany(targetEntity = AppBundle\Entity\ForumCategory,mappingBy = section)
* /
私人$类别;
公共功能__construct(){
$ this-> categories = new ArrayCollection();
}
公共函数getCategories(){
return $ this-> categories;
}
/ **
*添加类别
*
* @param AppBundle\Entity\ForumCategory
* @return ForumSection
* /
公共功能addCategory(\AppBundle\Entity\ForumCategory $ category)
{
$ this-> categories [] = $ category;
返回$ this;
}
/ **
*删除类别
*
* @param AppBundle\Entity\ForumCategory $ category
* /
公共功能removeCategory(\AppBundle\Entity\ForumCategory $ category)
{
$ this-> categories-&removeElement($ category);
}
/ **
* @ ORM\PrePersist
* @ ORM\PreUpdate
* /
公共功能UpdatedTimestamps(){
if($ this-> getCreatedAt()== null){
$ this-> setCreatedAt(new \DateTime('NOW')) ;
}
}
/ **
* @return混合
* /
公共函数getId(){
return $ this-> id;
}
/ **
* @return混合
* /
公共函数getTitle(){
return $ this->标题;
}
/ **
* @param $ title
* @return $ this
* /
public function setTitle($ title ){
$ this-> title = $ title;
返回$ this;
}
/ **
* @return混合
* /
公共函数getPosition(){
return $ this->位置;
}
/ **
* @param $ position
* @return $ this
* /
public function setPosition($ position ){
$ this-> position = $ position;
返回$ this;
}
/ **
* @返回日期
* /
公共函数getCreatedAt(){
return $ this-> created_at;
}
/ **
* @param $ date
* /
公共函数setCreatedAt($ date){
$ this- > created_at = $ date;
返回$ this;
}
}
ForumCategory.php
<?php
命名空间AppBundle\Entity;
/ **
* @版本0.0.1
* @版权所有(c)2015 Ricardo Jacobs。版权所有。
* @license专有和机密源代码。
* /
使用Doctrine\ORM\映射为ORM;
/ **
* @ ORM\Entity(repositoryClass = AppBundle\Entity\Repositories\Forum)
* @ ORM\Table(name = forum_categories)
* /
class ForumCategory
{
/ **
* @ ORM\Column(type = integer,name = id )
* @ ORM\Id
* @ ORM\GeneratedValue(strategy = AUTO)
* /
private $ id;
/ **
* @ ORM\ManyToOne(targetEntity = AppBundle\Entity\ForumSection,inversedBy = categories)
* @ ORM\JoinColumn (name = section,referencedColumnName = id)
* /
private $ section;
/ **
* @ ORM\Column(type = integer,name = position)
* /
private $ position;
/ **
* @ ORM\Column(type = string,length = 255,name = title)
* /
private $标题;
/ **
* @ ORM\Column(type = string,length = 255,nullable = true,name = description)
* /
私人$ description;
/ **
* @return混合
* /
公共函数getId(){
return $ this-> id;
}
/ **
* @return混合
* /
公共函数getSection(){
return $ this->部分;
}
/ **
* @param $ section
* @return $ this
* /
public function setSection($ section ){
$ this-> section = $ section;
返回$ this;
}
/ **
* @return混合
* /
公共函数getPosition(){
return $ this->位置;
}
/ **
* @param $ position
* @return $ this
* /
public function setPosition($ position ){
$ this-> position = $ position;
返回$ this;
}
/ **
* @return混合
* /
公共函数getTitle(){
return $ this->标题;
}
/ **
* @param $ title
* @return $ this
* /
public function setTitle($ title ){
$ this-> title = $ title;
返回$ this;
}
/ **
* @return混合
* /
公共函数getDescription(){
return $ this->描述;
}
/ **
* @param $ description
* @return $ this
* /
公共功能setDescription($ description ){
$ this-> description = $ description;
返回$ this;
}
}
控制器;
公共函数indexAction()
{
$ em = $ this-> get('doctrine')-> getManager() ;
$ sections = $ sections = $ this-> getDoctrine()-> getRepository('AppBundle:ForumSection')-> findAll();
返回$ this-&r; render('AppBundle:Default:index.html.twig',array('sections'=> $ sections));
}
模板;
< ol>
{%为论坛中%的部分}
< li>
< h2> {{forum.title}}< / h2>
< ul>
{forum.getCategories()中类别的百分比%}
< li> {{category.title}}}< / li>
{%endfor%}
< / ul>
< / li>
{%endfor%}
< / ol>
现在,您可以访问与数据库中每个forum_section行相关的类别。
这是我运行代码后的输出
-
hello
- 您好第1部分
- 您好第2部分
-
world
- 世界第1部分
- 世界第2部分
我不得不提到,Doctrine默认使用延迟加载.Doctrine将执行额外的查询以查找与论坛相关的类别。如果您有 n
个论坛,则将有 n + 1
个查询。在我的情况下,我使用了2个论坛部分,下面是查询。 > SELECT
t0.id AS id1,
t0.title AS title2,
t0.position AS position3,
t0.created_at AS created_at4
从
forum_sections t0
然后,对于每个论坛,主义都会执行另一个查询以查找具有不同参数的类别。
直到您调用'forum.getCategories()`方法,该查询才会执行。
SELECT
t0 .id AS id1,
t0.position AS位置2,
t0.title AS title3,
t0.description AS description4,
t0.section AS section5
FROM
forum_categories t0
t0.section =吗? [参数:1,2]
查看fetch-join概念,以了解有关延迟加载和替代方法的更多信息。
http://blog.bemycto.com/good-practices/2015-05-31/understanding-doctrine-orm-lazy-load-fetch-join/
I have the following tables (and entities in symfony2 / doctrine2):
+------------------+ +--------------------+
| forum_sections | | forum_categories |
+------------------+ +--------------------+
| id ├--------| | id |
| title | |---------| section |
| position | | position |
| created_at | | title |
+------------------+ | description |
+--------------------+
I want to archive the following html page (without the bullets ofcource):
- this is a title (from forum_sections->title)
- forum 1 (from forum_categories->title)
- forum 2 (from forum_categories->title)
- this is another title (from forum_sections->title)
- forum 3 (from forum_categories->title)
I did some research on how to do this. So far I tried the following in my twig layout:
{% for section in sections %}
<h1>title</h1>
{% for category in categories %}
bla bla
{% endfor %}
{% endfor %}
Is this even possible with a 'findAll' query in Doctrine2? I tried some combinations, but they seem to get all the boards ignoring the sections.
I think the problem is in your entities, the way you define the relationship between entitites. You need to use bidirectional mapping http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html#one-to-many-bidirectional
I updated your entities to fit your needs.
- Added categories to
ForumSection
entity - Added addCategory(), removeCategory(), getCategories() methods to
ForumSection
entity - Added
inversedBy
annotation toForumCategory
entity to complete te relationship - I used getCategories() method to get all the categories for the section in twig.
The entities;
ForumSection.php
namespace AppBundle\Entity;
/**
* @version 0.0.1
* @copyright (c) 2015 Ricardo Jacobs. All rights reserved.
* @license Proprietary and confidential source code.
*/
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\Repositories\Forum")
* @ORM\HasLifecycleCallbacks
* @ORM\Table(name="forum_sections")
*/
class ForumSection
{
/**
* @ORM\Column(type="integer", name="id")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, name="title")
*/
private $title;
/**
* @ORM\Column(type="integer", name="position")
*/
private $position;
/**
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\ForumCategory", mappedBy="section")
*/
private $categories;
public function __construct() {
$this->categories = new ArrayCollection();
}
public function getCategories() {
return $this->categories;
}
/**
* Add category
*
* @param AppBundle\Entity\ForumCategory
* @return ForumSection
*/
public function addCategory(\AppBundle\Entity\ForumCategory $category)
{
$this->categories[] = $category;
return $this;
}
/**
* Remove category
*
* @param AppBundle\Entity\ForumCategory $category
*/
public function removeCategory(\AppBundle\Entity\ForumCategory $category)
{
$this->categories->removeElement($category);
}
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updatedTimestamps() {
if ($this->getCreatedAt() == null) {
$this->setCreatedAt(new \DateTime('NOW'));
}
}
/**
* @return mixed
*/
public function getId() {
return $this->id;
}
/**
* @return mixed
*/
public function getTitle() {
return $this->title;
}
/**
* @param $title
* @return $this
*/
public function setTitle($title) {
$this->title = $title;
return $this;
}
/**
* @return mixed
*/
public function getPosition() {
return $this->position;
}
/**
* @param $position
* @return $this
*/
public function setPosition($position) {
$this->position = $position;
return $this;
}
/**
* @return Date
*/
public function getCreatedAt() {
return $this->created_at;
}
/**
* @param $date
*/
public function setCreatedAt($date) {
$this->created_at = $date;
return $this;
}
}
ForumCategory.php
<?php
namespace AppBundle\Entity;
/**
* @version 0.0.1
* @copyright (c) 2015 Ricardo Jacobs. All rights reserved.
* @license Proprietary and confidential source code.
*/
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\Repositories\Forum")
* @ORM\Table(name="forum_categories")
*/
class ForumCategory
{
/**
* @ORM\Column(type="integer", name="id")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\ForumSection", inversedBy="categories")
* @ORM\JoinColumn(name="section", referencedColumnName="id")
*/
private $section;
/**
* @ORM\Column(type="integer", name="position")
*/
private $position;
/**
* @ORM\Column(type="string", length=255, name="title")
*/
private $title;
/**
* @ORM\Column(type="string", length=255, nullable=true, name="description")
*/
private $description;
/**
* @return mixed
*/
public function getId() {
return $this->id;
}
/**
* @return mixed
*/
public function getSection() {
return $this->section;
}
/**
* @param $section
* @return $this
*/
public function setSection($section) {
$this->section = $section;
return $this;
}
/**
* @return mixed
*/
public function getPosition() {
return $this->position;
}
/**
* @param $position
* @return $this
*/
public function setPosition($position) {
$this->position = $position;
return $this;
}
/**
* @return mixed
*/
public function getTitle() {
return $this->title;
}
/**
* @param $title
* @return $this
*/
public function setTitle($title) {
$this->title = $title;
return $this;
}
/**
* @return mixed
*/
public function getDescription() {
return $this->description;
}
/**
* @param $description
* @return $this
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
}
The controller;
public function indexAction()
{
$em = $this->get('doctrine')->getManager();
$sections = $sections = $this->getDoctrine() ->getRepository('AppBundle:ForumSection') ->findAll();
return $this->render('AppBundle:Default:index.html.twig', array('sections'=>$sections));
}
The template;
<ol>
{% for forum in sections %}
<li>
<h2>{{forum.title}} </h2>
<ul>
{% for category in forum.getCategories() %}
<li>{{category.title}}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ol>
Now you have access to categories related to each forum_section row in your database.
And this is the output after I run the code
-
hello
- hello section 1
- hello section 2
-
world
- world section 1
- world section 2
I have to mention that Doctrine uses lazy loading by default.Doctrine will perform extra queries to find categories related to forums. If you have n
forums you will have n + 1
queries. In my case I used 2 forum sections and here are the queries.
This one finds all the forum_sections;
SELECT
t0.id AS id1,
t0.title AS title2,
t0.position AS position3,
t0.created_at AS created_at4
FROM
forum_sections t0
Then for each forum, doctrine executes another query to find categories with different parameters. This queries don't get executed untill you call 'forum.getCategories()` method.
SELECT
t0.id AS id1,
t0.position AS position2,
t0.title AS title3,
t0.description AS description4,
t0.section AS section5
FROM
forum_categories t0
WHERE
t0.section = ? [Parameters: 1,2]
Check out fetch-join concept to learn more about lazy loading and alternatives.
http://blog.bemycto.com/good-practices/2015-05-31/understanding-doctrine-orm-lazy-load-fetch-join/
这篇关于树枝模板中的ManyToOne的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!