首页 \ 问答 \ 在Symfony2中嵌入一个集合类型(Embed a collection type in Symfony2)

在Symfony2中嵌入一个集合类型(Embed a collection type in Symfony2)

试图嵌入一个集合类型,基本上遵循这里的一步一步的方法。

我收到以下错误:

The form's view data is expected to be an instance of class
AppBundle\Entity\BenefitGroup, but is an instance of class 
AppBundle\Entity\BenefitItem. You can avoid this error by setting the 
"data_class" option to null or by adding a view transformer that transforms 
an instance of class AppBundle\Entity\BenefitItem to an instance of 
AppBundle\Entity\BenefitGroup.

只是为了澄清,BenefitItem是父亲,而BenefitGroup是孩子。

我基本上得到了这个错误。

我还没有实现(还)允许你动态添加BenefitGroup元素的部分,我甚至没有尝试持久化对象或删除它(所以我没有实现Doctrine的最后一部分,如例)。

这是我的代码:

BenefitItem实体:

<?php
// src/AppBundle/Entity/BenefitItem.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\BenefitItemRepository")
 * @ORM\Table(name="benefit_items")
 */
class BenefitItem
{
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=400)
 */
protected $comment;

public function __construct()
{
    $this->BenefitGroups = new ArrayCollection();
}

public function getBenefitGroups()
{
    return $this->BenefitGroups;
}

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

/**
 * Set comment
 *
 * @param string $comment
 * @return BenefitItem
 */
public function setComment($comment)
{
    $this->comment = $comment;

    return $this;
}

/**
 * Get comment
 *
 * @return string 
 */
public function getComment()
{
    return $this->comment;
}
}

BenefitGroup实体:

<?php
// src/AppBundle/Entity/BenefitGroup.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\BenefitGroupRepository")
 * @ORM\Table(name="benefit_groups")
 */
class BenefitGroup
{
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=100)
 */
protected $name;

/**
 * @ORM\ManyToOne(targetEntity="BenefitItem", cascade={"persist"})
 * @ORM\JoinColumn(name="benefitItem_id")
 */
protected $benefitItem;


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

/**
 * Set name
 *
 * @param string $name
 * @return BenefitGroup
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string 
 */
public function getName()
{
    return $this->name;
}

/**
 * Set benefitItem
 *
 * @param \AppBundle\Entity\BenefitItem $benefitItem
 * @return BenefitGroup
 */
public function setBenefitItem(\AppBundle\Entity\BenefitItem $benefitItem = null)
{
    $this->benefitItem = $benefitItem;

    return $this;
}

/**
 * Get benefitItem
 *
 * @return \AppBundle\Entity\BenefitItem 
 */
public function getBenefitItem()
{
    return $this->benefitItem;
}
}

BenefitItemFormType:

<?php

namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class BenefitItemFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('comment');

    $builder->add('benefitgroups', 'collection', array('type' => new BenefitGroupFormType()));
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\BenefitGroup',
    ));
}

public function getName()
{
    return 'BenefitItem';
}
}

BenefitGroupFormType:

<?php

namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class BenefitGroupFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('name');
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\BenefitGroup',
    ));
}

public function getName()
{
    return 'BenefitGroup';
}
}

控制器:

<?php
// AppBundle\Controller\BenefitController.php

namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use AppBundle\Entity\BenefitItem;
use AppBundle\Entity\BenefitGroup;
use AppBundle\Form\Type\BenefitItemFormType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BenefitController extends Controller
{
/**
 * @Route("/benefit/show", name="benefit_show")
 */
public function showAction(Request $request)
{
    $BI = new BenefitItem();

    $BG1 = new BenefitGroup();
    $BG1->setName = 'Name 1';
    $BI->getBenefitGroups()->add($BG1);
    $BG2 = new BenefitGroup();
    $BG2->setName = 'Name 2';
    $BI->getBenefitGroups()->add($BG2);        

    $form = $this->createForm(new BenefitItemFormType(), $BI);

    $form->handleRequest($request);

    if ($form->isValid()) {
        // ... maybe do some form processing, like saving the Task and Tag objects
    }

    return $this->render('benefit/show.html.twig', array(
        'form' => $form->createView(),
    ));
}
}

任何想法?


Trying to embed a collection type, basically following the step by step approach here.

I get the following error:

The form's view data is expected to be an instance of class
AppBundle\Entity\BenefitGroup, but is an instance of class 
AppBundle\Entity\BenefitItem. You can avoid this error by setting the 
"data_class" option to null or by adding a view transformer that transforms 
an instance of class AppBundle\Entity\BenefitItem to an instance of 
AppBundle\Entity\BenefitGroup.

Just to clarify, the BenefitItem is the father while the BenefitGroup is the child.

I'm getting this error, basically.

I've not implemented (yet) the part that allows you to add BenefitGroup elements dynamically, and I'm not even trying to persist the object or remove it (so I did not implement yet the last part of the Doctrine as explained in the example).

Here is my code:

The BenefitItem entity:

<?php
// src/AppBundle/Entity/BenefitItem.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\BenefitItemRepository")
 * @ORM\Table(name="benefit_items")
 */
class BenefitItem
{
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=400)
 */
protected $comment;

public function __construct()
{
    $this->BenefitGroups = new ArrayCollection();
}

public function getBenefitGroups()
{
    return $this->BenefitGroups;
}

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

/**
 * Set comment
 *
 * @param string $comment
 * @return BenefitItem
 */
public function setComment($comment)
{
    $this->comment = $comment;

    return $this;
}

/**
 * Get comment
 *
 * @return string 
 */
public function getComment()
{
    return $this->comment;
}
}

The BenefitGroup entity:

<?php
// src/AppBundle/Entity/BenefitGroup.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\BenefitGroupRepository")
 * @ORM\Table(name="benefit_groups")
 */
class BenefitGroup
{
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=100)
 */
protected $name;

/**
 * @ORM\ManyToOne(targetEntity="BenefitItem", cascade={"persist"})
 * @ORM\JoinColumn(name="benefitItem_id")
 */
protected $benefitItem;


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

/**
 * Set name
 *
 * @param string $name
 * @return BenefitGroup
 */
public function setName($name)
{
    $this->name = $name;

    return $this;
}

/**
 * Get name
 *
 * @return string 
 */
public function getName()
{
    return $this->name;
}

/**
 * Set benefitItem
 *
 * @param \AppBundle\Entity\BenefitItem $benefitItem
 * @return BenefitGroup
 */
public function setBenefitItem(\AppBundle\Entity\BenefitItem $benefitItem = null)
{
    $this->benefitItem = $benefitItem;

    return $this;
}

/**
 * Get benefitItem
 *
 * @return \AppBundle\Entity\BenefitItem 
 */
public function getBenefitItem()
{
    return $this->benefitItem;
}
}

The BenefitItemFormType:

<?php

namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class BenefitItemFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('comment');

    $builder->add('benefitgroups', 'collection', array('type' => new BenefitGroupFormType()));
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\BenefitGroup',
    ));
}

public function getName()
{
    return 'BenefitItem';
}
}

The BenefitGroupFormType:

<?php

namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class BenefitGroupFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('name');
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\BenefitGroup',
    ));
}

public function getName()
{
    return 'BenefitGroup';
}
}

The controller:

<?php
// AppBundle\Controller\BenefitController.php

namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use AppBundle\Entity\BenefitItem;
use AppBundle\Entity\BenefitGroup;
use AppBundle\Form\Type\BenefitItemFormType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BenefitController extends Controller
{
/**
 * @Route("/benefit/show", name="benefit_show")
 */
public function showAction(Request $request)
{
    $BI = new BenefitItem();

    $BG1 = new BenefitGroup();
    $BG1->setName = 'Name 1';
    $BI->getBenefitGroups()->add($BG1);
    $BG2 = new BenefitGroup();
    $BG2->setName = 'Name 2';
    $BI->getBenefitGroups()->add($BG2);        

    $form = $this->createForm(new BenefitItemFormType(), $BI);

    $form->handleRequest($request);

    if ($form->isValid()) {
        // ... maybe do some form processing, like saving the Task and Tag objects
    }

    return $this->render('benefit/show.html.twig', array(
        'form' => $form->createView(),
    ));
}
}

Any idea?


原文:https://stackoverflow.com/questions/29260595
更新时间:2020-01-01 07:15

最满意答案

从图像看起来你想要一个支点,我相信你通过做到这一点来实现这一点

SELECT a.userid, u.name, u.profilePic,
    SUM(activity_weight) total_points,
    SUM(CASE WHEN activity_typeid=22 THEN activity_weight ELSE 0 END) activity22,
    SUM(CASE WHEN activity_typeid=33 THEN activity_weight ELSE 0 END) activity33,
    SUM(CASE WHEN activity_typeid=55 THEN activity_weight ELSE 0 END) activity55    
FROM activity_entries a 
INNER JOIN users1 u ON u.id = a.userid 
WHERE competitionId = '$competitionId' 
GROUP BY a.userid 
ORDER BY totalPoints

编辑注释:以下可能存在一些语法错误,但想法是动态创建sql然后执行它

-- generate sql for pivoted columns
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE WHEN activity_typeid=',activity_typeid,
      ' THEN activity_weight ELSE 0 END) AS activity_', activity_typeid, 
    )
  ) INTO @sql
FROM activity_entries;

-- place above in full select query
-- n.b. the `$competitionId` could be a problem my MySQL is not v. good
SET @sql = CONCAT('SELECT a.userid, u.name, u.profilePic,
                          SUM(activity_weight) total_points,', @sql,
                  'FROM activity_entries 
                   JOIN users1 u ON u.id = a.userid 
                   WHERE competitionId = ''$competitionId''   
                   GROUP BY a.userid, u.name, u.profilePic
                   ORDER BY totalPoints');

-- execute the dynamic sql
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

From the image it looks like you want a pivot, I believe in MySQL you achieve this by doing

SELECT a.userid, u.name, u.profilePic,
    SUM(activity_weight) total_points,
    SUM(CASE WHEN activity_typeid=22 THEN activity_weight ELSE 0 END) activity22,
    SUM(CASE WHEN activity_typeid=33 THEN activity_weight ELSE 0 END) activity33,
    SUM(CASE WHEN activity_typeid=55 THEN activity_weight ELSE 0 END) activity55    
FROM activity_entries a 
INNER JOIN users1 u ON u.id = a.userid 
WHERE competitionId = '$competitionId' 
GROUP BY a.userid 
ORDER BY totalPoints

Edit for comments: there may be some syntax errors in the following but the idea is to create the sql dynamically and then execute it

-- generate sql for pivoted columns
SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE WHEN activity_typeid=',activity_typeid,
      ' THEN activity_weight ELSE 0 END) AS activity_', activity_typeid, 
    )
  ) INTO @sql
FROM activity_entries;

-- place above in full select query
-- n.b. the `$competitionId` could be a problem my MySQL is not v. good
SET @sql = CONCAT('SELECT a.userid, u.name, u.profilePic,
                          SUM(activity_weight) total_points,', @sql,
                  'FROM activity_entries 
                   JOIN users1 u ON u.id = a.userid 
                   WHERE competitionId = ''$competitionId''   
                   GROUP BY a.userid, u.name, u.profilePic
                   ORDER BY totalPoints');

-- execute the dynamic sql
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

相关问答

更多

相关文章

更多

最新问答

更多
  • 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
  • Java中的不可变类(Immutable class in Java)
  • 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
  • linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
  • Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
  • 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
  • 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
  • Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
  • EXCEL VBA 基础教程下载
  • RoR - 邮件中的动态主体(部分)(RoR - Dynamic body (part) in mailer)
  • 无法在Google Script中返回2D数组?(Can not return 2D Array in Google Script?)
  • JAVA环境变量的设置和对path , classpth ,java_home设置作用和目的?
  • mysql 关于分组查询、时间条件查询
  • 如何使用PowerShell匹配运算符(How to use the PowerShell match operator)
  • Effective C ++,第三版:重载const函数(Effective C++, Third edition: Overloading const function)
  • 如何用DELPHI动态建立MYSQL的数据库和表? 请示出源代码。谢谢!
  • 带有简单redis应用程序的Node.js抛出“未处理的错误”(Node.js with simple redis application throwing 'unhandled error')
  • 使用前端框架带来哪些好处,相对于使用jquery
  • Ruby将字符串($ 100.99)转换为float或BigDecimal(Ruby convert string ($100.99) to float or BigDecimal)
  • 高考完可以去做些什么?注意什么?
  • 如何声明放在main之后的类模板?(How do I declare a class template that is placed after the main?)
  • 如何使用XSLT基于兄弟姐妹对元素进行分组(How to group elements based on their siblings using XSLT)
  • 在wordpress中的所有页面的标志(Logo in all pages in wordpress)
  • R:使用rollapply对列组进行求和的问题(R: Problems using rollapply to sum groups of columns)
  • Allauth不会保存其他字段(Allauth will not save additional fields)
  • python中使用sys模块中sys.exit()好像不能退出?
  • 将Int拆分为3个字节并返回C语言(Splitting an Int to 3 bytes and back in C)
  • 在SD / MMC中启用DDR会导致问题吗?(Enabling DDR in SD/MMC causes problems? CMD 11 gives a response but the voltage switch wont complete)
  • sed没有按预期工作,从字符串中间删除特殊字符(sed not working as expected, removing special character from middle of string)
  • 如何将字符串转换为Elixir中的函数(how to convert a string to a function in Elixir)