如何在不执行一长串“OR”操作的情况下找到模型的所有记录?状况?

发布于 2024-08-24 11:36:35 字数 812 浏览 5 评论 0原文

我在编写返回我正在查找的记录的 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

“帖子”表
编号
用户 ID
ETC

I'm having trouble composing a CakePHP find() which returns the records I'm looking for.

My associations go like this:

User ->(has many)-> Friends ,
User ->(has many)-> Posts

I'm trying to display a list of all a user's friends recent posts, in other words, list every post that was created by a friend of the current user logged in.

The only way I can think of doing this is by putting all the user's friends' user_ids in a big array, and then looping through each one, so that the find() call would look something like:

$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
                    )
                )           
            )
        ));

I get the impression this isn't the best way of doing things as if that user is popular that's a lot of OR conditions. Can anyone suggest a better alternative?

To clarify, here is a simplified version of my database:

"Users" table
id
username
etc

"Friends" table
id
user_id
friend_id
etc

"Posts" table
id
user_id
etc

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

童话 2024-08-31 11:36:35

在查看了您重写的内容后,我想我明白您在做什么。您当前的结构将不起作用。帖子里没有提到朋友。因此,根据您发布的架构,朋友无法添加任何帖子。我认为您想要做的是将朋友作为其他用户之一。意思是,用户 FRIEND 实际上只是 USERS 表中的另一个用户。这是一种自引用 HABTM 关系。所以这是我的建议:

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

-- MySQL CREATE TABLE users_users (user_id char(36) NOT NULL,
friend_id char(36) NOT NULL );

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

var $hasAndBelongsToMany = 数组(
'朋友' => array('className' => '用户',
  '加入表' => '用户_用户',
  '外键' => '用户身份',
  'associationForeignKey' =>; '朋友 ID',
  '独特' =>真的,
  ),
);

var $hasMany = 数组(
'发布' =>大批(
  '类名' => '邮政',
  '外键' => '用户身份'
),
);

3-使用脚手架插入一些记录,链接好友并添加帖子。
4-在Users控制器中添加查看记录功能:

函数 get_user($id)
{
  $posts = $this->用户->find('第一个', array(
      '条件' => array('User.id' => $id),
      '递归' => ‘2’
  ));
  pr($帖子);
}

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

http://test/users/get_user/USER_ID

6- 您的输出将显示所有记录 (当您 pr($posts) 递归地)将朋友及其帖子包含在返回的数据树中时,

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

快乐编码!

After reviewing what you have rewritten, I think I understand what you are doing. Your current structure will not work. There is no reference in POSTS to friends. So based on the schema you have posted, friends CANNOT add any POSTS. I think what you are trying to do is reference a friend as one of the other users. Meaning, A users FRIEND is actually just another USER in the USERS table. This is a self referential HABTM relationship. So here is what I would propose:

1- First, make sure you have the HABTM table created in the DB:

-- MySQL CREATE TABLE users_users ( user_id char(36) NOT NULL,
friend_id char(36) NOT NULL );

2- Establish the relationships in the User model.

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- use the scaffolding to insert a few records, linking friends and adding posts.
4- Add the view record function to the Users controller:

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

5- Now you can query the User table using recursive to pull the records using the following command:

http://test/users/get_user/USER_ID

6- Your output will show all of the records (recursively) including the friends and their posts in the returned data tree when you pr($posts)

I know this is a long post, but I think it will provide the best solution for what you are trying to do. The power of CakePHP is incredible. It's the learning curve that kills us.

Happy Coding!

满身野味 2024-08-31 11:36:35

如果 Post.user_id 指向 Friend.id (不遵循 convention 顺便说一句)那么这将

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

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

If Post.user_id points to Friend.id (which wouldn't follow the convention btw) then it would be

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

which would result in .. WHERE Post.user_id IN (1, 2, 3) ..

二手情话 2024-08-31 11:36:35

根据您的设置,运行两个查询可能比尝试通过 Cake 内容将它们链接在一起更快。我建议在 Users 模型中添加类似 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,
特拉维斯

Depending on your setup, it might be quicker to run two queries rather than trying to chain them together via the Cake stuff. I'd recommend adding something like getFriendsPosts() in the Users model.

<?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;
  }
 }
?>

Then to call it, in the controller just do

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

HTH,
Travis

你穿错了嫁妆 2024-08-31 11:36:35

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)",
));

Isn't CakePHP already generating the efficient code of:

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

if not, you can do

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

$posts = $this->Posts->find('all', array(
    'conditions' => "Post.user_id IN ($conditions)",
));
浊酒尽余欢 2024-08-31 11:36:35

如果您的模型正确关联,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);

If your models are properly associated, Cake will automatically retrieve related model records. So, when you search for a specific user, Cake will automatically retrieve related friends, and related posts of these friends. All you need to do is set the recursion level high enough.

$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()
        )
    )
)

All you need to do is extract the posts from the user's friends, which is as easy as:

$postsOfFriends = Set::extract('/Friend/Post/.', $user);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文