Laravel 5.6嵌套查询关系

时间:2018-10-26 02:44:00

标签: laravel relationship

嗨,我需要询问深厚的感情...

我的article { width: 50%; display: inline-block; float: none; } 模型

store

我的<?php namespace App\Model; use Illuminate\Database\Eloquent\Model; class Store extends Model { protected $table = 'stores'; public function address(){ return $this->morphOne('App\Model\Address', 'addressable'); } } 模型

Address

我的class Address extends Model { protected $table = 'address'; protected $fillable = [ 'province_id', 'city_id', 'brgy_id', 'street_lot_blk', 'longitude', 'latitude' ]; public function addressable(){ return $this->morphTo(); } public function province(){ return $this->hasOne('App\Model\Province', 'id', 'province_id'); } public function city(){ return $this->hasOne('App\Model\City', 'id', 'city_id'); } public function brgy(){ return $this->hasOne('App\Model\Brgy', 'id', 'brgy_id'); } } 模型

province

我的查询

<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class Province extends Model
{

    protected $table = 'refprovince';
}

$request = app()->make('request'); return response()->json([ 'stores' => Store::where('name', 'LIKE', '%'. $request->name . '%') ->with(['address.province', 'address.city', 'address.brgy']) ->take(10)->get() ]); 见所附照片

enter image description here

问题是,如果用户键入商店名称,则只会返回商店名称;如果用户键入“ Camarines”,则只会返回在省内带有“ Camarines”字样的商店。

我的代码看起来像这样...但是它不起作用。

result

我不知道是否可以告诉我,以便我可以重新构建数据库。 TY

更新:仍然不适用于这些代码。

 $results = Store::where('name', 'LIKE', '%'. $request->name . '%')
                    ->with(['address.province' => function($query) use ($request) {

                        $query->where('provDesc', 'LIKE', '%'. $request->name . '%');

                    }])
                    ->take(10)->get();

        return response()->json([
                'stores' => $results
            ]);

enter image description here

2 个答案:

答案 0 :(得分:1)

您的代码存在的问题是with()不会限制查询或向查询中添加条件。它仅告诉Laravel在运行第一个查询之后稍后(在另一个查询中)加载哪些关系。您传递的回调将限制在辅助查询期间加载的模型,但在确定要检索的商店时并没有约束。

当前显示为:

  • 加载前(最多)10个名称为%name%的商店
    • 为每个返回的(最多)10个ID加载地址(在ID上运行whereIn()查询)
      • 为每个地址加载省份,但前提是provDesc像%name%(再次对地址ID进行whereIn()查询)

解决方案:添加 orWhereHas()到商店的查询中:

Store::where('name', 'LIKE', "%$foo%")

    ->orWhereHas('address.province', function ($query) {
        $query->where('provDesc', 'LIKE', "%$foo%");
    });

但是仍然使用with()来包含您要使用的关系:

$stores = Store::where('name', 'LIKE', "%{$request->name}%")
    ->orWhereHas('address.province', function ($query) use ($request) {
        $query->where('provDesc', 'LIKE', "%{$request->name}%");
    })
    ->with('address.province')
    ->take(10)
    ->get();

或者如果您希望地址的省份关系仅在匹配时才加载 %name%:

$stores = Store::where('name', 'LIKE', "%{$request->name}%")
    ->orWhereHas('address.province', function ($query) use ($request) {
        $query->where('provDesc', 'LIKE', "%{$request->name}%");
    })
    ->with(['address.province' => function ($query) use ($request) {
        $query->where('provDesc', 'LIKE', "%{$request->name}%");
    }])
    ->take(10)
    ->get();

答案 1 :(得分:0)

2件事:

  1. 您需要一个OR子句来搜索一个或另一个条件为真(商店名称与搜索匹配或省份provDesc与搜索匹配)的记录。您可以使用orWhere()向查询中添加OR子句。

https://laravel.com/docs/5.6/queries#where-clauses

  1. 商店是您在这里的主要搜索结果,而各省是相关记录。 with()方法不会过滤主要结果,只会过滤与主要结果一起返回的相关模型。要通过查询相关记录来过滤主要结果,请使用whereHas()(或orWhereHas()whereDoesntHave()等)。

https://laravel.com/docs/5.6/eloquent-relationships#querying-relationship-existence

尝试这样的事情:

$results = Store::whereHas('province', function($query) use ($request) {
    $query->where('provDesc', 'LIKE', '%'. $request->name . '%');
})->orWhere('name', 'LIKE', '%'. $request->name . '%');