4

我在编写返回我正在寻找的记录的 CakePHP find() 时遇到问题。

我的联想是这样的:

用户 ->(有很多)-> 朋友,
用户 ->(有很多)-> 帖子

我正在尝试显示所有用户朋友最近帖子的列表,换句话说,列出由当前登录用户的朋友创建的每个帖子。

我能想到的唯一方法是将所有用户朋友的 user_ids 放入一个大数组中,然后循环遍历每个数组,以便 find() 调用看起来像:

$posts = $this->Post->find('all',array(
            'conditions' => array(
                'Post.user_id' => array(
                    'OR' => array(
                        $user_id_array[0],$user_id_array[1],$user_id_array[2] # .. etc
                    )
                )           
            )
        ));

我的印象是,这不是最好的做事方式,好像该用户很受欢迎,这是很多 OR 条件。任何人都可以提出更好的选择吗?

为了澄清,这是我的数据库的简化版本:

“用户”表
id
用户名

“朋友” 表
id
user_idfriend_id

“帖子”表
id
user_id

4

5 回答 5

2

在回顾了你重写的内容之后,我想我明白你在做什么。您当前的结构将无法正常工作。POSTS 中没有对朋友的引用。因此,根据您发布的架构,朋友不能添加任何帖子。我认为您要做的是将朋友引用为其他用户之一。意思是,A users FRIEND 实际上只是 USERS 表中的另一个 USER。这是一个自我参照的 HABTM 关系。所以这是我的建议:

1-首先,确保您在数据库中创建了 HABTM 表:

-- MySQL 创建表users_users( user_idchar(36) NOT NULL,
friend_idchar(36) NOT NULL);

2- 在用户模型中建立关系。

var $hasAndBelongsToMany = array(
'friend' => array('className' => 'User',
  'joinTable' => 'users_users',
  'foreignKey' => 'user_id',
  'associationForeignKey' => 'friend_id',
  'unique' => true,
  ),
);

var $hasMany = array(
'Post' => array(
  'className' => 'Post',
  'foreignKey' => 'user_id'
),
);

3-使用脚手架插入一些记录,链接朋友和添加帖子。4-将查看记录功能添加到用户控制器:

function get_user($id)
{
  $posts = $this->User->find('first', array(
      'conditions' => array('User.id' => $id),
      'recursive' => '2'
  ));
  pr($posts);
}

5-现在您可以使用以下命令使用递归查询用户表以提取记录:

http://test/users/get_user/USER_ID

6- 当您 pr($posts) 时,您的输出将显示所有记录(递归),包括返回的数据树中的朋友和他们的帖子

我知道这是一篇很长的文章,但我认为它将为您尝试做的事情提供最佳解决方案。CakePHP 的强大功能令人难以置信。杀死我们的是学习曲线。

快乐编码!

于 2010-03-08T15:32:47.497 回答
0

如果Post.user_id指向Friend.id(不遵循惯例),那么它将是

$posts = $this->Post->find('all',array(
    'conditions' => array(
        'Post.user_id' => $user_id_array      
    )
);

这将导致.. WHERE Post.user_id IN (1, 2, 3) ..

于 2010-03-08T15:24:18.327 回答
0

根据您的设置,运行两个查询可能比尝试通过 Cake 东西将它们链接在一起更快。我建议在用户模型中添加类似 getFriendsPosts() 的东西。

<?php
 class UserModel extends AppModel {
 // ... stuff
  function getFriendsPosts( $user_id )
  {
   $friends = $this->find( ... parameters to get user IDs of all friends );
   // flatten the array or tweak your params so they fit the conditions parameter.  Check out the Set class in CakePHP
   $posts = $this->find( 'all', array( 'conditions' => array( 'User.id' => $friends ) ) );
   return $posts;
  }
 }
?>

然后调用它,在控制器中执行

$friends = $this->User->getFriendsPosts( $this->Auth->User('id') );

HTH,特拉维斯

于 2010-03-08T17:56:07.500 回答
0

CakePHP 不是已经生成了以下有效代码:

SELECT * from Posts WHERE user_id IN (id1, id2 ...)

如果没有,你可以做

$conditions='NULL';
foreach($user_id_array as $id) $conditions.=", $id";

$posts = $this->Posts->find('all', array(
    'conditions' => "Post.user_id IN ($conditions)",
));
于 2010-03-09T00:07:01.893 回答
0

如果您的模型正确关联,Cake 将自动检索相关的模型记录。因此,当您搜索特定用户时,Cake 会自动检索相关好友,以及这些好友的相关帖子。您需要做的就是将递归级别设置得足够高。

$user = $this->User->find('first', array('conditions' => array('User.id' => $id), 'recursive' => 2));
debug($user);

// gives something like:
array(
    User => array()
    Friend => array(
        0 => array(
            ...
            Post => array()
        ),
        1 => array(
            ...
            Post => array()
        )
    )
)

您需要做的就是从用户的朋友中提取帖子,这很简单:

$postsOfFriends = Set::extract('/Friend/Post/.', $user);
于 2010-03-09T02:23:04.400 回答