Laravel 使用预加载而不是进行 3 次查询

huangapple go评论69阅读模式
英文:

Laravel using eager loading instead of making 3 queries

问题

Visit 模型:

class Visit extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'customer_id',
        'report',
        'appointment_date',
        'appointment_time',
    ];

    protected $dates = ['appointment_date'];

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

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

Customer 模型:

class Customer extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'city',
        'address',
        'email_address',
        'phone_number',
    ];
}

我有一个脚本,用于检查客户是否需要新的约会(如果将来没有新的约会,并且上次约会已经超过5个月,或者还没有约会):

$customers = Customer::get();
foreach ($customers as $customer) {
    $newVisit = $customer->visits()->whereInFuture()->first();
    // 如果客户已经计划了将来的约会,请继续
    if ($newVisit !== null) {
        continue;
    }

    // 这也会检索具有空约会日期的访问,这对于尚未计划但已计划的约会是必要的
    $lastVisit = $customer->visits()->orderBy('appointment_date', 'desc')->first();
    // 客户尚无访问记录
    if ($lastVisit === null) {
        $this->createNewAppointment($customer);
        continue;
    }

    $lastVisitDate = new Carbon($lastVisit->appointment_date);
    // 客户的最后一次约会已经超过..个月了
    if ($lastVisitDate->diffInMonths() > $this->argument('months')) {
        $this->createNewAppointment($customer);
        continue;
    }
}

是否有一种方法可以使用 eager loading 仅运行1个查询?还是这是不可能的,因为我需要检索新的访问和最后的访问?

英文:

I am trying to improve at laravel, the story here is that I have customers, customers can have appointments and users create appointments for the customers.

Visit model:

class Visit extends Model
{
    use HasFactory;

    protected $fillable = [
        'user_id',
        'customer_id',
        'report',
        'appointment_date',
        'appointment_time',
    ];

    protected $dates = ['appointment_date'];

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

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

Customer model:

class Customer extends Model
{
    use HasFactory;

    protected $fillable = [
        'name',
        'city',
        'address',
        'email_address',
        'phone_number',
    ];

I have a script that checks if the customer should have a new appointment (this happens if there is no new appointment in the future and when the last appointment is longer than 5 months ago or there is no appointment yet:

$customers = Customer::get();
foreach ($customers as $customer) {
    $Newvisit = $customer->visits()->whereInFuture()->first();
    // continue if the customer already has an appointment planned in the future
    if ($Newvisit !== null) {
        continue;
    }

    // This also retrieves visits with null appointment date, this is neccesary for appointments that are not schedulded but already planned
    $lastVisit = $customer->visits()->OrderBy('appointment_date', 'desc')->first();
    // Customer has no visits yet
    if ($lastVisit === null) {
        $this->createNewAppointment($customer);
        continue;
    }

    $lastVisitDate = new Carbon($lastVisit->appointment_date);
    // Last appointment for customer is longer than .. months ago
    if ($lastVisitDate->diffInMonths() > $this->argument('months')) {
        $this->createNewAppointment($customer);
        continue;
    }
}

Is there a way to use eager loading to only run 1 query? or is this impossible since I need to retrieve a new visit and last visit

答案1

得分: 1

以下是翻译好的部分:

在客户模型中有一个与访问相关的关系。

public function visits()
{
    return $this->hasMany(Visit::class);
}

然后,您可以获取客户数据如下:

$customers = Customer::with('visits')->get();

或者您可以像这样对访问进行排序 -

$customers = Customer::with(['visits' => function ($query) {
    $query->orderBy('appointmemt_date', 'desc');
}])->get();

然后 $customer->visits->first(); 可能会让您知道这是新访问还是最后一次访问。

英文:

There is a relationship in customer model to get visits.

public function visits()
{
    return $this->hasMany(Visit::class);
}

Then you can fetch customers data as $customers = Customer::with('visits')->get();

Or you can order visits like this -

$customers = Customer::with(['visits' => function ($query) {
  $query->orderBy('appointmemt_date', 'desc');
}])->get();

Then $customer->visits->first(); may give you inkling whether it is New visit or Last Visit.

答案2

得分: 0

你可以定义自定义关系。似乎,你可以定义新访问和上次访问的关系。

英文:

You can define custom relationships. Seems, you can define relations for newVisit and lastVisit.

huangapple
  • 本文由 发表于 2023年5月11日 03:40:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76222051.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定