【问题标题】:Filter results from a laravel collection based on the related record根据相关记录过滤来自 laravel 集合的结果
【发布时间】:2017-01-18 19:06:39
【问题描述】:

我在我的 Laravel 项目中使用 https://github.com/nicolaslopezj/searchable

我有一个与用户有多对多关系的 Hotel 对象。

我可以使用这个查询关系:

protected $searchable = [
    'columns' => [
        'hotels.nombre' => 10
    ],
    'joins' => [
        'hotel_user' => ['hotels.id' , 'hotel_id'],
        'users' => ['hotel_user.user_id', 'users.id']
    ]
];

搜索返回类似这样的内容(json 格式)

 [
  {
    "id": 3,
    "nombre": "Paradisus Playa del Carmen La Esmeralda",
    "url_foto": "uploads/hotel/3/1484747239.jpg",
    "website_url": "https://www.melia.com/es/hoteles/mexico/playa-del-carmen/home.htm",
    "updated_at": "2017-01-18 13:47:44",
    "relevance": 60,
    "users": [
      {
        "id": 1,
        "first_name": "Alex",
        "last_name": "Angelico",
        "formatted_name": "Alex",
        "company": "ConexionBIZ",
        "title": "Director",
        "picture_url": "https://media.licdn.com/mpr/mprx/0_FIUn3Wf5E4OMEwzR5feW3o7IoRSveSkR5W7d3oxczOM5BdPUwDws7EIJXvDEIE5c6HMeaSSFgb19",
        "created_at": "2017-01-17 12:00:00",
        "updated_at": "2017-01-18 13:50:19",
        "pivot": {
          "hotel_id": 3,
          "user_id": 1,
          "created_at": null,
          "updated_at": null
        }
      }
    ]
  },

我想过滤属于某个特定用户的所有酒店。 我试过了:

 $result = \App\Hotel::search($request->get('q'))->with([
            'users' => function($q) use ($user_id) {
                $q->where('users.id', '<>', $user_id);
            },
        ])->get();

但这会返回没有相关用户的酒店。我需要从结果中删除酒店(不仅仅是用户)。

我该怎么做?

非常感谢!

【问题讨论】:

    标签: laravel-5 eloquent


    【解决方案1】:

    with() 方法实际上是在检索到 Hotel 集合后作为第二个查询运行的,用于延迟加载。

    您正在寻找的是whereHas(),它将根据相关模型过滤当前模型结果。

    $result = \App\Hotel::search($request->get('q'))
        ->whereHas('users', function($q) use ($user_id) {
            $q->where('users.id', '<>', $user_id);
        })
        ->get();
    

    这将返回所有具有与$user_id 不匹配的用户的Hotel 模型。

    如果您也需要加载用户,那么:

    $result = \App\Hotel::search($request->get('q'))
        ->with('users')
        ->whereHas('users', function($q) use ($user_id) {
            $q->where('users.id', '<>', $user_id);
        })
        ->get();
    

    这将加载至少有 1 个用户与 $user_id 不匹配的所有 Hotel 模型,但 $result-&gt;first()-&gt;users 集合仍然可以包含具有该 ID 的用户。要不返回任何具有 $user_idHotel 模型并且不返回相关集合中的任何用户,您可以结合使用这两种方法:

    $result = \App\Hotel::search($request->get('q'))
        ->with(['users' => function($q) use ($user_id) {
            $q->where('users.id', '<>', $user_id);
        }])
        ->whereHas('users', function($q) use ($user_id) {
            $q->where('users.id', '<>', $user_id);
        })
        ->get();
    

    【讨论】:

    • 顺便说一句,我是 Laravel 的新手,我很难找到好的文档。 Laravel 的站点对我来说似乎不够用,Laracast 很适合开始,但是现在......你对关于 Laravel 5.3 的好的文档或文献有什么建议吗? TKS!
    • 我的大部分知识来自 Laravel 文档。我建议您彻底阅读他们的文档一次,以便为您提供更高层次的概述,这样当您遇到问题时,您可以大致了解文档是否/在哪里涵盖了它。一旦你学习了命名约定和基本上是“Laravel”的方式,文档就变得更容易浏览了。如果您也有任何问题,请随时联系我。我总是愿意帮助开发人员!干杯!
    猜你喜欢
    • 2022-01-08
    • 2016-04-26
    • 2018-10-10
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多