【问题标题】:Laravel: get data from variouos tables based on optional conditionsLaravel:根据可选条件从各种表中获取数据
【发布时间】:2016-10-12 15:53:04
【问题描述】:

我想编写一个基于可选条件的查询,该条件将从不同的表中获取数据。我的架构看起来像

myboxes 表

 id,
 type_id    --> foreign key to box_type table
 postal_code  
 po_box
 created_at
 updated_at

mybox_access 表

 id
 mybox_id   -> foreign key to myboxes table
 email

box_type 表

id
type_name

这是我的模型 MyBox.php

class MyBox extends Model {
    public function type() {
        return this->hasOne(BoxType::class, 'id', 'type_id');
    }

    public function access() id
        return this->hasOne(MyBoxAccess::class, 'mybox_id', 'type_id');
    }
}

MyBoxType.php 有如下关系

  public function mybox() {
        return this->hasOne(MyBox::class, 'id', 'type_id');
    }

和MyBoxAccess.php有如下关系

  public function vbox() {
      return $this->belongsTo(MyBox::class, 'id', 'mybox_id');
  }

现在我想根据以下条件得到 我将电子邮件作为必需参数,将 postal_code 和 po_box 作为可选参数(但其中一个是必须的,并且两者都可以存在)。

所以我想获取 type_id 为 3 的所有 my_boxes 的数据,或者 mybox_access 表中与电子邮件匹配的所有 myboxes 的数据,并且 postal_code 或 po_box 与 myboxes 表中的参数匹配

对于 params 邮政编码和 po_box 的简单匹配,我可以写一些类似的东西

 $result = new MyBox();
 if(!empty($request['postal_code'])) {
     $result->where('postal_code', like, '%'.$request['postal_code']);
 }
 if(!empty($request['po_box'])) {
     $result->where('po_box', like, '%'.$request['po_box']);
 }
 $result = $result->get();

但我不知道如何获取上述条件的数据。当我尝试使用with() 时,就像

MyBox::with(['access' => function(Builder $query) use ($request){
     $query->where('mybox_id',$request['id']);
}])->get();

我明白了

`Argument 1 Passed to {closure} () must be an instance of Illuminat\Database\Query\Builder, instance of Illuminate\Databaase\Eloquent\Relation\HasOne given`

任何机构都可以告诉我如何根据上述条件获取数据

【问题讨论】:

    标签: laravel eloquent


    【解决方案1】:

    $query 是关系,而不是构建器实例。

    所以这不应该抛出任何异常。

    MyBox::with(['access' => function ($query) {
        $query->where('mybox_id', $request['id']);
    }])->get();
    

    但我认为它不会解决您的问题,因为您的 Box 访问关系不正确。应该是 HasMany。

    // MyBox.php
    public function type()
    {
        return $this->hasOne(BoxType::class, 'id', 'type_id');
    }
    public function access()
    {
        return $this->hasMany(MyBoxAccess::class, 'mybox_id', 'id');
    }
    

    然后在你的控制器中你可以做到这一点。

    // $results where type_id is 3
    $results = MyBox::where('type_id', 3)->get();
    
    // List of boxes accessible by email
    $results = MyBox::whereHas('access', function ($query) {
        $query->where('email', request()->input('email'));
    })->get();
    
    // Results where postal_code and po_box matches the request
    $results = MyBox::with('access')->where(function ($query) {
        if (request()->has('postal_code')) {
            $query->where('postal_code', 'like', '%' . request()->input('postal_code'));
        }
        if (request()->has('po_box')) {
            $query->where('po_box', 'like', '%' . request()->input('po_box'));
        }
    })->get();
    

    如果你想合并所有条件:

    $results = MyBox::where(function ($query) {
        if (request()->has('type_id')) {
            $query->where('type_id', request()->input('type_id'));
        }
        if (request()->has('email')) {
            $query->whereHas('access', function ($query) {
                $query->where('email', request()->input('email'));
            });
        }
        if (request()->has('postal_code')) {
            $query->where('postal_code', 'like', '%' . request()->input('postal_code'));
        }
        if (request()->has('po_box')) {
            $query->where('po_box', 'like', '%' . request()->input('po_box'));
        }
    })->get();
    

    在闭包中使用时,我总是使用request() 门面,感觉更干净。

    【讨论】:

    • 我会使用->get() 3 次吗?
    • 这取决于。您询问了 3 种不同类型的结果(基于 type_id OR email OR postal_code/po_box)。你当然可以只使用 1 个->get()
    • @SimponDepelchin 很好我如何将它们组合成一个->get() 就像每次都会有类型 id 和 emaill 以及 post_code 或 po_box 之一的必备条件?比如 where (type_id = 3 or email = myemail) and (post_code =12 or po_box = 12)?
    • @AwaisQarni 我编辑了我的帖子,添加了所有条件合并的示例。根据需要随意更改条件(if/elseif/else)。
    【解决方案2】:

    试试这个查询:

    MyBox::with('access')->get();
    

    【讨论】:

    • 它会解决我在问题中提出的所有问题吗?
    猜你喜欢
    • 1970-01-01
    • 2022-01-22
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2021-11-29
    • 2021-02-08
    相关资源
    最近更新 更多