【问题标题】:Laravel - Filter morphOne or hasOne relationshipLaravel - 过滤 morphOne 或 hasOne 关系
【发布时间】:2018-09-12 01:09:21
【问题描述】:

我有三个通过morph 关系相关的模型。

Shipment 可以通过StatusHistory 类拥有多个Status 实例。

    class Status extends Model {
       //id, name
    }

    class Shipment extends Model {
       public function latestStatus() {
          return $this->morphOne('App\StatusHistory', 'model')->latest();
       }
    }

    class StatusHistory extends Model {
       public function model() {
            return $this->morphTo();
        }

        public function status() {
           return $this->belongsTo('App\Status', 'status_id');
        }
    }

我想获取 latestStatus 具有特定 Status 名称值的所有 Shipment 实体。

   Shipment::whereHas('latestStatus', function($query) {
      return $query->whereHas('status', function($query) {
         return $query->where('name', 'reserved');
      });
   })->get();

这不起作用并返回所有状态为“已保留”的实体,即使 latestStatus 可以是别的东西。

有什么想法吗?

编辑(添加示例信息):

我有 2 批货物。

  1. 第一个只有一个状态历史实例,其状态名称为“已保留”。
  2. 第二个有两个状态历史实例,其状态名称为“已保留”和“已发货”。 'shipped' 的状态历史实例是在 'reserver' 之后创建的。

所以:

  1. 第一批货物的最后状态为“已保留”。
  2. 第二批货物的最后状态为“已发货”。

调用应该只返回第一批货物。

【问题讨论】:

    标签: laravel laravel-5 laravel-5.5 laravel-5.6


    【解决方案1】:

    最简单的解决方案是获取所有货物并在之后对其进行过滤:

    Shipment::with('latestStatus.status')->get()->where('latestStatus.status.name', 'reserved')
    

    根据您的数据库大小,这可能不是很有效。

    只获取相关货物的查询:

    Shipment::select('shipments.*')
        ->join('status_histories as sh', 'shipments.id', 'sh.model_id')
        ->join('statuses as st', 'sh.status_id', 'st.id')
        ->where('model_type', Shipment::class)
        ->where('st.name', 'reserved')
        ->where('created_at', function($query) {
            $query->selectRaw('MAX(created_at)')
                ->from('status_histories')
                ->where('model_id', DB::raw('sh.model_id'))
                ->where('model_type', DB::raw('sh.model_type'));
        })->get();
    

    【讨论】:

    • 我收到Unknown column 'latestStatus.status.name'
    • 你把->get()移到最后了吗?
    • 你不能把它移到最后。查询必须保持我发布的方式。
    • 但是数据库很难,因为可能有很多状态历史实例。如果这些增长,查询也会随着时间增长。
    • 我将编写更有效的查询。 StatusHistoryStatus 之间是否存在 BelongsTo 关系?
    猜你喜欢
    • 2020-10-06
    • 2021-07-27
    • 2017-10-01
    • 2015-02-16
    • 2020-03-04
    • 1970-01-01
    • 2018-05-29
    • 2017-04-21
    • 2016-03-17
    相关资源
    最近更新 更多