通过匹配集合值附加新的键和值

Attach new key and value by matching collection value

你好伟大的 SO 人!

首先,如果我的英语不是很好,我很抱歉,但我会尽力在这里描述我的问题

我有 3 个模型

  1. 用户
  2. Post
  3. 喜欢

User.php

___________________________________________________________
| id  | name | email | password | created_at | updated_at |
| ... | ...  | ...   | ...      | ...        | ...        |
| ... | ...  | ...   | ...      | ...        | ...        |
| ... | ...  | ...   | ...      | ...        | ...        |

User model relationship:

public function posts() {
    return $this->hasMany(Post::class, 'user_id', 'id');
}

Post.php

__________________________________________________
| id  | user_id | body | created_at | updated_at |
| ... | ...     | ...  | ...        | ...        |
| ... | ...     | ...  | ...        | ...        |

Post model relationship:

public function user() {
    return $this->belongsTo(User::class, 'user_id', 'id');
}

public function likes() {
    return $this->morphMany('likeable');
}

Like.php

_________________________________________________________________________
| id  | likeable_type | likeable_id | user_id | created_at | updated_at |
| ... | ...           | ...         | ...     | ...        | ...        |
| ... | ...           | ...         | ...     | ...        | ...        |
| ... | ...           | ...         | ...     | ...        | ...        |

Like model relationship:

public function likeable() {
    return $this->morphTo('likeable');
}

一切正常,简单来说 C.R.U.D

当我使用Laravel Debugbar时出现问题, 我看到这么多重复查询只是为了获取几条记录:

Ex:
    // Let say that I have 5 users
    $users = User::all();

    foreach ($users as $user) {
        $user->load('posts');
    }

    return $users;

    // Result
    select * from `posts`.`user_id` 1 ...
    select * from `posts`.`user_id` 2 ...
    select * from `posts`.`user_id` 3 ...

So I decide to change the method

Ex:
    $users = User::all();

    $posts = Post::whereIn('user_id', $users->pluck('id')->toArray())->get();

    // Result:
    select * `posts`.`user_id` in (1, 2, 3, 4, 5)

我不再看到重复的查询,这很好, 解决了这个重复查询后,我从特定的 posts

中获取 'likes'
Ex:
    $users = User::all();

    $posts = Post::whereIn('user_id', $users->pluck('id')->toArray())->get();

    $posts_likes = Like::where('likeable_type', 'App\Post') // morphMany
                ->whereIn('likeable_id', $posts->pluck('id')->toArray())->get();
    

现在问题来了,我不知道如何将 posts_likes 配对到它的 post

Ex:
    $posts = [
        {
            'id': 1,
            'user_id': 2,
            'body': 'Lorem ipsum...',
            ...
        },
        {
            'id': 2,
            'user_id': 2,
            'body': 'Sit amet...',
            ...
        },
        {
            'id': 3,
            'user_id': 3,
            'body': 'abcde...',
            ...    
        },
        ... etc
    ];

    $posts_likes = [
        {
            'id': 1,
            'likeable_type': 'App\Post',
            'likeable_id': 2,
            'user_id': 3,
            ...
        },
            'id': 2,
            'likeable_type': 'App\Post',
            'likeable_id': 2,
            'user_id': 2,
            ...
        {
            'id': 3,
            'likeable_type': 'App\Post',
            'likeable_id': 1,
            'user_id': 5,
            ...
        },
        {
            'id': 4,
            'likeable_type': 'App\Post',
            'likeable_id': 3,
            'user_id': 1,
            ...
        },
        ... etc
    ];

我的问题:

如何通过匹配准确的 ID 在 $posts 集合中插入赞? (post id == 喜欢 likeable_id)

所以我可以循环访问它们,例如:$post->likes = [...]

Ex:
    $posts = [
        {
            'id': 1,
            'user_id': 2,
            'body': 'Lorem ipsum...',
            'likes': [
                // All likes for post with this id (1)
            ],
            ...
        },
        {
            'id': 2,
            'user_id': 2,
            'body': 'Sit amet...',
            'likes': [
                // All likes for post with this id (2)
            ],
            ...
        },
        ...
    ];

如有不明白的地方,我会编辑a.s.a.p 提前致谢

你可以轻松加载所有这些

ref link https://laravel.com/docs/8.x/eloquent-relationships#nested-eager-loading

$users = User::with('posts.likes')->get();
return $users;

如果您设置正确的关系,此代码将起作用

//user model
public function posts()
{
    return $this->hasMany(Post::class, 'user_id', 'id');
}

//post model
public function likes()
{
    return $this->morphMany('likeable');
}

我想生成 json link

[{
    "name": "user",
    "posts": [{
            "name": "postName",
            "likes": []
        },
        {
            "name": "postName",
            "likes": []
        }
    ]
}]