【问题标题】:Symfony: Get Posts of FriendsSymfony:获取朋友的帖子
【发布时间】:2016-01-31 15:00:19
【问题描述】:

我想知道是否有人可以为我指出正确的方向,如何让用户的所有朋友的帖子合并某种新闻流

我有一个简单的用户实体 $user->getPosts() 和 $user->getFriends() 它通过学说中的相应关系设置返回适当的帖子/用户对象。这些工作正常,但我如何将我所有朋友的所有帖子编译成一个 ArrayCollection 帖子?

我能想到的唯一方法是遍历所有朋友,获取帖子,将它们合并到一个数组中,然后执行一些排序...但这听起来有点复杂/性能不佳

我不认为 $user->getFriends()->getPosts() 也可以简单地进行,我将如何正确排序帖子以获得唯一最新的帖子?我也想知道性能问题。给定一个用户有很多朋友,从数据库中检索到的数据会非常多。有效地征服它的最佳方法是什么?还是因为 symphony 的延迟加载,我根本不担心这个?

感谢您的帮助!

这是用户实体

AppBundle\Entity\User:
type: entity
repositoryClass: AppBundle\Entity\UserRepository
table: user
indexes:
    id:
        columns:
            - id
uniqueConstraints:
    username:
        columns:
            - username
    handle:
        columns:
            - handle
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: true
        id: true
        generator:
            strategy: IDENTITY
fields:
    username:
        type: string
        nullable: false
        length: 30
        options:
            fixed: false
    password:
        type: string
        nullable: false
        length: 60
        options:
            fixed: false
    email:
        type: string
        nullable: false
        length: 60
        options:
            fixed: false
oneToMany:
    images:
        targetEntity: Image
        mappedBy: user
    posts:
        targetEntity: Post
        mappedBy: user
    postcomments:
        targetEntity: Postcomment
        mappedBy: user
oneToOne:
    sedcard:
        targetEntity: Sedcard
        mappedBy: user
    portfolio:
        targetEntity: Portfolio
        mappedBy: user
manyToMany:
    myFriends:
        targetEntity: User
        joinTable:
            name: friend
        joinColumns:
            user_source:
                referencedColumnName: id
        inverseJoinColumns:
            user_target:
                referencedColumnName: id
        inversedBy: friendsWithMe
    friendsWithMe:
        targetEntity: User
        mappedBy: myFriends                    
lifecycleCallbacks: {  }

这里是帖子实体

AppBundle\Entity\Post:
type: entity
table: post
indexes:
    user_id:
        columns:
            - user_id
id:
    id:
        type: integer
        nullable: false
        options:
            unsigned: true
        id: true
        generator:
            strategy: IDENTITY
fields:
    userId:
        type: integer
        nullable: false
        options:
            unsigned: true
        column: user_id
    body:
        type: text
        nullable: false
        length: 65535
        options:
            fixed: false
    type:
        type: boolean
        nullable: false
    created:
        type: datetime
        nullable: false
    active:
        type: boolean
        nullable: false
oneToMany:
    postcomments:
        targetEntity: Postcomment
        mappedBy: post
manyToOne:
    user:
        targetEntity: User
        inversedBy: posts
        joinColumn:
            name: user_id
            referencedColumnName: id
lifecycleCallbacks: {  }

【问题讨论】:

  • 扩展实体并编写自己的函数。

标签: php symfony posts


【解决方案1】:
<?php

namespace AppBundle\Repository;

/**
 * PostRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class PostRepository extends \Doctrine\ORM\EntityRepository
{
    public function findAllPostsOfFriends($userId)
    {
        return $this->getEntityManager()
            ->createQuery(
                'SELECT p, u FROM AppBundle:Post p ' .
                'JOIN p.user u ' .
                'JOIN u.friendsWithMe f ' . 
                'WHERE f.id=:userId'
            )->setParameter('userId', $userId)
            ->getResult();
    }
}

说明:

开始选择所有帖子:(我们想将 p 和 u(帖子和作者)选择到内存中,以避免当我们想将作者的一些信息显示为嗯。你可以在调试栏上统计由教义所做的查询。(删除,u并查看结果)

SELECT p, u FROM AppBundle:Post p

然后从帖子中加入作者的完整用户实体

JOIN p.user u

接下来加入所有与作者为好友的用户的用户实体

JOIN u.friendsWithMe f

最后但并非最不重要的一点是,仅筛选所有作者的一位朋友(我自己)

WHERE f.id=:userId

控制者:

public function indexAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();

    // give the user.id as parameter from who you want to see the posts of all his friends
    $posts = $em->getRepository('AppBundle:Post')->findAllPostsOfFriends(2); 

    return $this->render('default/index.html.twig', array(
        'posts' => $posts
    ));
}

模板:

{% extends 'base.html.twig' %}

{% block body %}
    <ul>
        {% for post in posts %}
            <li>{{ post.body }} <strong>Author: {{ post.user.username }}</strong></li>
        {% endfor %}
    </ul>
{% endblock %}

【讨论】:

  • 非常感谢!这让我更清楚了!
  • 虽然这很有效,但我无法为上帝的爱弄清楚如何将我自己的帖子添加到流中(在 where 添加“或 u.id=:userId”,在all)我也无法弄清楚如何添加反向“myFriends”约束(因为它是用户 A->B 或 B->A,友谊是双向的)。这甚至可能吗?
【解决方案2】:

对于这项工作,您不想再使用 $user->getPosts() 函数,因为这将给出该用户之前发布的帖子的列表。您想要的是一个带有“发布”实体的数组,但只有来自所有“发布”实体而不是所有实体的选定组。为此,您需要使用高级 DQL 查询。接下来开始在您的用户实体旁边使用存储库。然后在您的存储库中编写一个自定义函数,该函数仅检索用户他的朋友的帖子。

阅读:

Querying for Objects with DQL

Custom Repository Classes

DQL and joins

只有当您发布相关实体时,我们才能进一步帮助您

【讨论】:

  • 谢谢,我已将实体配置附加到原始问题中。创建自定义存储库类不会有问题,但我需要查询方面的帮助,因为我真的不知道如何进行连接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多