计算 Laravel 关系中的雄辩模型

问题描述 投票:0回答:1

我想计算每个评论对某个任务有多少个文件。我有一个 Laravel 项目(项目管理应用程序),具有以下模型:ProjectBoardTaskCommentFile。以下是每个模型中定义的关系。

// 项目模型


<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;

class Project extends Model
{
  use HasFactory;

  protected $fillable = [
    'name',
    'description',
    'due_date',
    'created_by',
    'contact_id',
    'status',
  ];

  public function boards(): HasMany
  {
    return $this->hasMany(Board::class);
  }

  public function files()
  {
    return $this->morphMany(File::class, 'fileable');
  }

  protected static function boot()
  {
    parent::boot();

    static::creating(function ($project) {
      $project->pid = Str::orderedUuid();
    });

    static::updating(function ($project) {
      if (!isset($project->pid)) {
        $project->pid = Str::orderedUuid();
      }
    });
  }
}

// 板模型


<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Board extends Model
{
  use HasFactory;

  protected $fillable = [
    'name',
    'project_id',
  ];

  public function project(): BelongsTo
  {
    return $this->belongsTo(Project::class);
  }

  public function tasks(): HasMany
  {
    return $this->hasMany(Task::class);
  }
}

// *任务模型


<?php

namespace App\Models;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Stevebauman\Purify\Casts\PurifyHtmlOnGet;

class Task extends Model
{
  use HasFactory;

  protected $fillable = [
    'name',
    'description',
    'assigned_to',
    'board_id',
    'position',
    'priority'
  ];

  public function board(): BelongsTo
  {
    return $this->belongsTo(Board::class);
  }

  public function comments(): HasMany
  {
    return $this->hasMany(Comment::class);
  }

  public function files(): HasManyThrough
  {
    return $this->hasManyThrough(
      File::class,
      Comment::class,
      'id',
      'model_id',
      'id',
      'id'
    )->where('model_type', Comment::class);
  }
}

// 评论模型


<?php

namespace App\Models;

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

class Comment extends Model
{
    use HasFactory;

  protected $fillable = [
    'body',
    'task_id',
    'user_id',
  ];

  public function task()
  {
    return $this->belongsTo(Task::class);
  }

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

  public function files()
  {
    return $this->morphMany(File::class, 'model');
  }
}

// 文件模型

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class File extends Model
{
  use HasFactory;

  protected $guarded = [];

  public function model(): MorphTo
  {
    return $this->morphTo();
  }

  protected static function boot()
  {
    parent::boot();

    static::creating(function ($file) {
      $file->fid = Str::orderedUuid();
    });

    static::updating(function ($file) {
      if (!isset($file->fid)) {
        $file->fid = Str::orderedUuid();
      }
    });
  }
}

我尝试过:

$project->load([
        'boards.tasks.user',
        'boards.tasks.comments.user',
        'boards.tasks.comments.files',
        'boards.tasks' => function ($query) {
          $query->withCount('comments');
        },
        'boards.tasks.comments' => function ($query) {
          $query->withCount('files');
        }
      ])

但它返回files_count,只显示了comments_count

我也尝试过

$project->load([
        'boards.tasks.user',
        'boards.tasks.comments.user',
        'boards.tasks.comments.files',
        'boards.tasks' => function ($query) {
          $query->withCount(['comments', 'files']); // trying to ustilize the **hasManyThrough** 
        },
      ])

但它仍然没有返回 files_count,只显示 comments_count

eloquent laravel-8
1个回答
0
投票

经过多次尝试和思考,我找到了解决方案。解决办法如下:

<?php

namespace App\Http\Controllers\Projects;

use App\Data\ProjectFullData;
use App\Http\Controllers\Controller;
use App\Models\Comment;
use App\Models\Project;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class Show extends Controller
{
  public function __invoke(Project $project)
  {
    $project = ProjectFullData::from(
      $project->load([
        'contact.firm',
        'contact.emails',
        'boards.tasks.user',
        'boards.tasks.comments.user',
        'boards.tasks.comments.files',
        'boards.tasks' => function ($query) {
          $query->withCount(['comments', 'files']);
        },
      ])
    );

    return Inertia::render('Projects/Show', [
      'project' => $project
    ]);

  }
}

我在评论中添加了

withCount
,并在一个子查询中添加了
files

© www.soinside.com 2019 - 2024. All rights reserved.