Laravel Eloquent使用'和#39;和'其中'

时间:2017-07-18 19:30:47

标签: eloquent laravel-5.4

使用Laravel 5.4

我正在伸出手来,因为我很难绕过这个问题并且在互联网上搜索了一整天(和stackoverflow)之后我找不到解决我的问题的好方法。

基本上,我有一个用户对象,它查询子对象,而子对象又包含一个子对象,我需要在该孙对象上使用where进行过滤。

看起来像这样:

User =>
    Pet(1) =>
        PetServiceItem <= ServiceItem(1)
        PetServiceItem <= ServiceItem(2)
        PetServiceItem <= ServiceItem(3)
    Pet(2) =>
        PetServiceItem <= ServiceItem(1)
        PetServiceItem <= ServiceItem(4)
        PetServiceItem <= ServiceItem(5)

我会发布信息的相关部分,以便有人可以告诉我如何做到这一点。

用户模型

class User extends Authenticatable
{
    public function pets()
    {
        return $this->hasMany(Pet::class);
    }

}

宠物模型

class Pet extends Model
{
    protected $fillable = [
        'id',
        'user_id',
        ...];

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

    public function petServiceItems(){
        return $this->hasMany(PetServiceItem::class);
    }
}

PetServiceItem模型

class PetServiceItem extends Model
{
    protected $fillable = [
        'pet_id',
        'service_item_id',
        'approved'
    ];

    protected $table = 'pet_service_item';

    public function pet()
    {
        return $this->belongsTo(Pet::class);
    }

    public function serviceItem()
    {
        return $this->belongsTo(ServiceItem::class);
    }
}

ServiceItem模型

class ServiceItem extends Model
{
    protected $fillable = [
        'id',
        ...,
        'start_date',
        'end_date',
        '...',
    ];

    public function pets(){
        return $this->hasMany(PetServiceItem::class);
    }
}

使用 Tinker 我可以执行以下操作: $user->pets()->with(['petServiceItems', 'petServiceItems.service'])->get()

获取此数据:

=> Illuminate\Database\Eloquent\Collection {#1118
     all: [
       App\Pet {#1120
         id: 1,
         user_id: 6,
         name: "Coco",
         slug: "carol!coco",
         image: "/dist/images/pets/carol/coco.jpg",
         breed: null,
         color: null,
         gender: "Female",
         birthdate: "2013-07-06 03:58:46",
         fixed: 0,
         weight: "48",
         licensed: "",
         tattoo: "",
         microchip: "",
         created_at: "2017-07-17 17:37:54",
         updated_at: "2017-07-17 17:37:54",
         petServiceItems: Illuminate\Database\Eloquent\Collection {#1126
           all: [
             App\PetServiceItem {#1132
               id: 1,
               provider_id: 2,
               pet_id: 1,
               service_item_id: 1,
               approved: 1,
               created_at: "2017-07-17 17:37:57",
               updated_at: "2017-07-17 17:37:57",
               serviceItem: App\ServiceItem {#1137
                 id: 1,
                 provider_id: 2,
                 type: "WALK",
                 subtype: "",
                 title: "7am 30min Walk between 7am and 10am",
                 desc: "Daily weekday walks between 7am and 10am",
                 day1: 0,
                 day2: 1,
                 day3: 1,
                 day4: 1,
                 day5: 1,
                 day6: 1,
                 day7: 0,
                 needs_approval: 0,
                 start_date: "2017-07-17 00:00:00",
                 end_date: "2017-10-17 00:00:00",
                 all_day: 0,
                 start_time: "07:00:00",
                 end_time: "10:00:00",
                 duration: 30,
                 pricing_one: 2000,
                 pricing_twoplus: 1800,
                 created_at: "2017-07-17 17:37:57",
                 updated_at: "2017-07-17 17:37:57",
                 deleted_at: null,
               },
             },
             App\PetServiceItem {#1134
               id: 3,
               provider_id: 2,
               pet_id: 1,
               service_item_id: 4,
               approved: 0,
               created_at: "2017-07-17 17:37:57",
               updated_at: "2017-07-17 17:37:57",
               serviceItem: App\ServiceItem {#1139
                 id: 4,
                 provider_id: 2,
                 type: "AGILITY",
                 subtype: "",
                 title: "10am Agility Tu/Th",
                 desc: "Agility class @ 10am Tuesdays and Thursdays for 90 minutes",
                 day1: 0,
                 day2: 0,
                 day3: 1,
                 day4: 0,
                 day5: 1,
                 day6: 0,
                 day7: 0,
                 needs_approval: 1,
                 start_date: "2017-07-17 00:00:00",
                 end_date: "2017-09-17 00:00:00",
                 all_day: 0,
                 start_time: "10:00:00",
                 end_time: "11:30:00",
                 duration: 90,
                 pricing_one: 5000,
                 pricing_twoplus: 4500,
                 created_at: "2017-07-17 17:37:57",
                 updated_at: "2017-07-17 17:37:57",
                 deleted_at: null,
               },
             },
           ],
         },
       },
       App\Pet {#1123
         id: 2,
         user_id: 6,
         name: "Ruby",
         slug: "carol!ruby",
         image: "/dist/images/pets/carol/ruby.jpg",
         breed: null,
         color: null,
         gender: "Female",
         birthdate: "2012-06-16 22:47:43",
         fixed: 1,
         weight: "53",
         licensed: "",
         tattoo: "",
         microchip: "",
         created_at: "2017-07-17 17:37:54",
         updated_at: "2017-07-17 17:37:54",
         petServiceItems: Illuminate\Database\Eloquent\Collection {#1119
           all: [
             App\PetServiceItem {#1133
               id: 2,
               provider_id: 2,
               pet_id: 2,
               service_item_id: 1,
               approved: 1,
               created_at: "2017-07-17 17:37:57",
               updated_at: "2017-07-17 17:37:57",
               serviceItem: App\ServiceItem {#1137},
             },
             App\PetServiceItem {#1135
               id: 4,
               provider_id: 2,
               pet_id: 2,
               service_item_id: 4,
               approved: 0,
               created_at: "2017-07-17 17:37:57",
               updated_at: "2017-07-17 17:37:57",
               serviceItem: App\ServiceItem {#1139},
             },
           ],
         },
       },
     ],
   }

现在我需要在 start_date 的ServiceItem上执行 where 子句。

我试过了:

$user->pets()->with(['petServiceItems', 'petServiceItems.serviceItem'])->where('service_items.start_date', '>=', '2017-01-01')->get()

但是,我收到了这个错误:

  

使用消息&#39; SQLSTATE [42S22]照亮\ Database \ QueryException:   未找到列:1054未知列&#39; service_items.start_date&#39;在   &#39; where where&#39; (SQL:select {from pets其中petsuser_id = 6   和petsuser_id不为空且service_itemsstart_date&gt; =   2017年1月1日)&#39;

如何使用 where 子句(或其他需要的东西)来过滤我需要的数据?

编辑: 我已经发现这是我想要的SQL(或接近足够的近似值):

select * from users 
join (select * from pets) pet on users.id = pet.user_id
join (select * from pet_service_item) psi on psi.pet_id = pet.id
join (select * from service_items) si on si.id = psi.service_item_id
join (select * from providers) prov on prov.id = si.provider_id
where si.start_date >= '2017-07-17' 
  AND si.end_date <= '2017-10-18'
  AND prov.id = 2
  AND users.id = 6

2 个答案:

答案 0 :(得分:0)

Where子句使用表的名称而不是模型。试试这个:

    $user->pets()->with(['petServiceItems', 'petServiceItems.serviceItem'])
->where('service_items.start_date', '>=', '2017-01-01')->get();

答案 1 :(得分:0)

所以,我发布这个,因为我从来没有真正得到答案,我最终得到了一个解决方案,但不完全是我正在寻找的解决方案。

如果有人有兴趣,最后,我就是这样做的(请注意:这会使数据变得平坦,无论出于什么意图和目的,在我的场景中都能正常工作)。

$services = App\ServiceItem::where('provider_id', '=', $provider->id)
    ->where('user.user_id', '=', $user->id)

    ->where('start_date', '<=', $end_date)
    ->where('end_date', '>=', $start_date)
    ->orWhereNull('end_date')

    ->where('pet.pet_user_id', '=', $user->id)
    ->whereNull('service_items.deleted_at')
    ->whereNUll('pet.pet_deleted_at')

    ->join(DB::raw('(select pet_id as psi_pet_id, service_item_id as psi_service_item_id from pet_service_items) psi'), function($join) {
        $join->on('psi.psi_service_item_id', '=', 'service_items.id');
    })

    ->join(DB::raw('(select id as pet_id, user_id as pet_user_id, name as pet_name, deleted_at as pet_deleted_at from pets) pet'), function($join) {
        $join->on('pet.pet_id', '=', 'psi.psi_pet_id');
    })

    ->join(DB::raw('(select id as user_id, name as user_name, deleted_at as user_deleted_at from users) user'), function($join) {
        $join->on('user.user_id', '=', 'pet.pet_user_id');
    });

return ['status' => 200, 'services' => $services->get()];