Symfony2 doctrine过滤器集合

时间:2015-11-27 16:47:06

标签: php symfony doctrine-orm

我有一些教义实体,每个实体都有一个OneToMany-Relationship:First:Base,Second:Module and Third:ModuleDetails(详见下文)。设置完美。在获取基础时,我获得所有模块以及相关的详细信息。

我的问题是:模块的细节可能会随着时间而变化,因此每当更改细节时,DB中都会有一个新条目,并相应地设置了修订日期。

现在我想要提供一个包含所有模块和详细信息的Base,但只有最新版本的Details(或我选择的任何修订版本),但我对此感到迷茫!

我可以为moduleDetails编写一个自定义的getter方法,它只能获得符合给定条件的那些吗?我已经读过关于Critera-Class的学说,但却无法让它发挥作用。任何帮助或提示都非常受欢迎。非常感谢你提前!

例如,这是我的实体(简称):

基础实体

/**
 * @ORM\Entity(repositoryClass="hcs\AlphaBundle\Entity\OfferBaseRepository")
 * @ORM\Table(name="hcs_offerbase")
 * @ORM\HasLifecycleCallbacks
 *
 * @ExclusionPolicy("all")
 */

class OfferBase
{
    /**
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      * @Type("integer")
      * @SerializedName("id")
      * @Groups({"list", "detail"})
      *
      * @Expose
    */
    protected $id;
    /**
      * @ORM\OneToMany(targetEntity="ModuleBase", mappedBy="offerbase", cascade={"persist", "merge"})
      * @Type("ArrayCollection<hcs\AlphaBundle\Entity\ModuleBase>")
      * @Assert\Valid
      *
      * @Expose
    */
    protected $category;

模块的实体:

/**
 * @ORM\Entity(repositoryClass="hcs\AlphaBundle\Entity\ModuleBaseRepository")
 * @ORM\Table(name="hcs_modulebase")
 *
 * @ExclusionPolicy("all")
 */

class ModuleBase
{
    /**
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      * @Type("integer")
      * @SerializedName("id")
      *
      * @Expose
    */
    protected $id;

    /**
      * @ORM\ManyToOne(targetEntity="OfferBase", inversedBy="category")
      * @ORM\JoinColumn(name="offerbase_id", referencedColumnName="id")
    */
    protected $offerbase;

    /**
      * @ORM\OneToMany(targetEntity="ModuleCondition", mappedBy="modulebase", cascade={"persist", "merge"})
      * @Type("ArrayCollection<hcs\AlphaBundle\Entity\ModuleCondition>")
      * @Assert\Valid
      *
      * @Expose
    */
    protected $modules;

ModuleDetails实体

/**
 * @ORM\Entity(repositoryClass="hcs\AlphaBundle\Entity\ModuleConditionRepository")
 * @ORM\Table(name="hcs_modulecondition")
 * @ORM\HasLifecycleCallbacks
 *
 * @ExclusionPolicy("all")
 */

class ModuleCondition
{
    /**
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      * @Type("integer")
      * @SerializedName("id")
      *
      * @Expose
    */
    protected $id;

    /**
      * @ORM\ManyToOne(targetEntity="ModuleBase", inversedBy="modules")
      * @ORM\JoinColumn(name="modulebase_id", referencedColumnName="id")
    */
    protected $modulebase;

编辑12.02.2015 坦克供你评论:

@Wilt: 我完全按照你在答案中提出的建议(为了测试目的,我使用id作为标准):

所以在我的模块实体中我做了:

   /**
     * Get modules
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function setModules()
    {
        $criteria = Criteria::create()
          ->where(Criteria::expr()->gte('id', '1'));

          return $this->details->matching($criteria);
    }

但考虑到你的答案,我认为我错了。从我的数据库中取出整个实体后,我必须在我的控制器中使用此过滤器,而不是过滤集合。

我是对的吗?

如果我这样做,是否有可能使用filterd集合来序列化实体?我使用JMS Serializer。

@General 这用于REST-Api。您可以通过发送ID(offerbase_id)获取任何优惠,并获得序列化优惠及其所有详细信息:

$currentOffer = $this->getDoctrine()->getRepository('myBundle:OfferBase')->find($offerId);

$serializer = $this->get('jms_serializer');
$result = $serializer->serialize($currentOffer, 'json');
return new Response($result);

作为普通用户,您只能访问最新版本的优惠,但如果您的user_role允许,您可以访问所有修订版本。我无法在客户端进行过滤。

1 个答案:

答案 0 :(得分:2)

在Doctrine文档 8.8 filter collections 中有一段关于如何执行此操作的内容。

您可以使用Doctrine\Common\Collections\Criteria类,并使用修订日期添加标准以过滤集合。

这样的事情:

$criteria = Criteria::create()
    ->where(Criteria::expr()->gte('revision_date', $date));

return $this->details->matching($criteria);