根据相关记录过滤laravel集合的结果

时间:2017-01-18 19:06:39

标签: laravel-5 eloquent

我在Laravel Project中使用https://github.com/nicolaslopezj/searchable

我有一个与用户有很多关系的酒店对象。

我可以使用以下方法查询关系:

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

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

我该怎么做?

非常感谢!

1 个答案:

答案 0 :(得分: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();

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

如果您还需要加载用户:

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

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

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