【问题标题】:Laravel filter one to many relationshipLaravel 过滤一对多关系
【发布时间】:2020-12-22 14:41:32
【问题描述】:

我正在尝试过滤具有一对多关系的模型上的查询,但它不起作用。正确的输出应该删除所有过期的库存,但它会返回所有可用的库存。

产品:hasMany(Stock::class)
库存:belongsTo(Product::class)

代码:

$keyword = $request->keyword;
$data = Product::with('stocks')
            ->where([
                ['pharmacy_id', '=', auth()->user()->pharmacy->id],
            ])
            ->where(function($productModel) use($keyword) {
                $productModel->where('name', 'LIKE', "%$keyword%")->orWhere('sku', 'LIKE', "%$keyword%");
            })
            ->whereHas('stocks', function($stockModel) {
                $stockModel->where('expiry', '>', Carbon::now()->format('Y-m-d'));
            })->get();

当前输出:

[
  {
    "id": 1,
    "sku": "xpzidfa1454995",
    "name": "Jaqueline Will",
    "category": "medicine",
    "type": "manufactured",
    "selling_price": "1.00",
    "pharmacy_id": 1,
    "created_at": "2020-12-22T11:40:32.000000Z",
    "updated_at": "2020-12-22T11:40:32.000000Z",
    "stocks": [
      {
        "id": 3,
        "product_id": 1,
        "expiry": "2025-10-10",
        "amount": 40,
        "supplier_id": 1,
        "pharmacy_id": 1,
        "created_at": "2020-12-22T11:45:39.000000Z",
        "updated_at": "2020-12-22T11:45:39.000000Z"
      },
      {
        "id": 5,
        "product_id": 1,
        "expiry": "2020-10-10",
        "amount": 40,
        "supplier_id": 1,
        "pharmacy_id": 1,
        "created_at": "2020-12-22T11:45:39.000000Z",
        "updated_at": "2020-12-22T11:45:39.000000Z"
      }
    ]
  }
]

正确的输出:

[
  {
    "id": 1,
    "sku": "xpzidfa1454995",
    "name": "Jaqueline Will",
    "category": "medicine",
    "type": "manufactured",
    "selling_price": "1.00",
    "pharmacy_id": 1,
    "created_at": "2020-12-22T11:40:32.000000Z",
    "updated_at": "2020-12-22T11:40:32.000000Z",
    "stocks": [
      {
        "id": 3,
        "product_id": 1,
        "expiry": "2025-10-10",
        "amount": 40,
        "supplier_id": 1,
        "pharmacy_id": 1,
        "created_at": "2020-12-22T11:45:39.000000Z",
        "updated_at": "2020-12-22T11:45:39.000000Z"
      }
    ]
  }
]

库存型号:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Stock extends Model
{
    use HasFactory;

    protected $fillable = [
        'product_id',
        'expiry',
        'amount',
        'supplier_id',
        'pharmacy_id',
    ];

    public function pharmacy() {
        return $this->belongsTo(Pharmacy::class);
    }

    public function product() {
        return $this->belongsTo(Product::class);
    }
}

【问题讨论】:

  • 我认为你不需要在 Laravel 中格式化 Carbon 对象。只需使用Carbon::now()
  • @Daan 哦,好吧,不知道,谢谢!但这并不能解决我的问题。

标签: php mysql database laravel


【解决方案1】:

要删除过期的股票记录,应将约束放在急切负载上

$keyword = $request->keyword;
$data = Product::with(['stocks' => fn($query) => $query->whereDate('expiry', '>', now())])
    ->where([
        ['pharmacy_id', '=', auth()->user()->pharmacy->id],
    ])
    ->where(function($productModel) use($keyword) {
        $productModel->where('name', 'LIKE', "%$keyword%")->orWhere('sku', 'LIKE', "%$keyword%");
    })
    ->get();

【讨论】:

  • 这成功了!你知道这对性能有没有好处?
  • 通过急切加载,避免了N+1查询的问题。所以急切加载实际上对性能有好处。根据应用程序的上下文和 Product 模型的记录数,您可以使用分页而不是获取所有记录
【解决方案2】:

我认为您应该使用whereDate 匹配日期。

试试这个,

$keyword = $request->keyword;
$data = Product::with('stocks')
            ->where([
                ['pharmacy_id', '=', auth()->user()->pharmacy->id],
            ])
            ->where(function($productModel) use($keyword) {
                $productModel->where('name', 'LIKE', "%$keyword%")->orWhere('sku', 'LIKE', "%$keyword%");
            })
            ->whereHas('stocks', function($stockModel) {
                $stockModel->whereDate('expiry', '>', Carbon::now()->format('Y-m-d'));
            })->get();

查看此链接了解更多

Laravel Additional Where Clauses

【讨论】:

  • 我试过了,但还是一样的输出
  • 然后使用now()。而是格式化日期。
  • 还是一样的输出。我猜 where 子句的链接是错误的,但我无法找到正确的方法。
猜你喜欢
  • 1970-01-01
  • 2018-05-20
  • 1970-01-01
  • 2018-04-19
  • 2013-09-14
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多