【问题标题】:Laravel add condition inside model public function relationLaravel 在模型公共函数关系中添加条件
【发布时间】:2021-05-20 07:40:25
【问题描述】:

我正在开发一个使用 Laravel 7.0 的预订系统

所以在这个系统中,我创建了一个名为“bookings”的表

我创建了它的模型,名为 Booking.php

在这个 Booking.php 中,我放入了关联函数以将其模型加入到事务表中,如下所示

public function transaction()
    {
        return $this->belongsTo('App\Models\Transaction', 'id', 'booking_id');
    }

突然有一个新要求进来了,这个预订将有它的孩子

为了区分预订父母和它的孩子,我在预订表中添加了一个名为

的新列

'parent_booking_id'

我不想过多更改代码功能,所以我正在考虑制定条件以确保预订点与正确交易的关系

我正在考虑编写这样的代码

public function transaction()
    {
        return $this->belongsTo('App\Models\Transaction', 'parent_booking_id' ?? 'id', 'booking_id');
    }

但它没有按预期工作

逻辑是

如果 parent_booking_id 存在,则将表 transaction 中的 'booking_id' 列连接到表 bookings 中的 'parent_booking_id' 列

其他

它将表事务中的“booking_id”列连接到表预订中的“id”列

【问题讨论】:

  • 是的,很明显它不起作用,因为'parent_booking_id' 是一个字符串,因此始终是参数。您可以尝试$this->parent_booking_id ? 'x' : 'y',但为了清晰起见,创建 2 个关系可能会更好
  • 已经尝试过$this->parent_booking_id,但它总是返回null,所以不能用作条件,如何在不更改已经使用事务函数的当前代码的情况下创建2个关系

标签: php laravel eloquent laravel-7


【解决方案1】:

我不确定我是否理解了所有内容。

我没有在模型中使用这种逻辑,但如果你真的想要的话。我不确定,但我认为这可行。

 public function parent_booking()
 {
     $this->belongsTo('App\Models\Booking', 'parent_booking_id');
 }

 public function transaction()
 {
     if ($this->has('parent_booking')) {
          return $this->hasOne('App\Models\Transaction', 'parent_booking_id', 'booking_id');
     } else {
          return $this->hasOne('App\Models\Transaction', 'booking_id');
     }
 }

如果您尝试实现的目标是: 当预订有 parent_booking 时,将交易附加到 parent_booking,否则,将其附加到预订。

要做到这一点,我的建议是做更多这样的事情。

 public function parent_booking()
 {
     $this->belongsTo('App\Models\Booking', 'parent_booking_id');
 }

 public function childs_booking()
 {
     $this->hasMany('App\Models\Booking', 'parent_booking_id');
 }

然后,您可以在控制器中执行此操作:

$booking = Booking::with('parent_booking')->find($id);
if ($booking->has('parent_booking')) {
    //do some stuff.
    $booking->parent_booking->transaction->associate($transaction->id);
} else {
    //do other stuff
    $booking->transaction->associate($transaction->id);
}

当然,您会想要检索正确的交易。有一个检索每个预订的示例。

$bookings = Booking::with(array('parent_booking', function($query) {
    return $query->with('transaction');
}))->with('transaction')->get();

foreach($bookings as $booking) {
    if ($booking->has('parent_booking')) {
        $transaction_to_use = $booking->parent_booking->transaction;
    } else {
        $transaction_to_use = $booking->transaction;
    }
}

您还可以执行以下操作:

$transactions = Transaction::with(array('booking', function($query) {
    return $query->with('childs_booking');
}))->get();

这样您就可以通过他们的预订获得每笔交易。您也有每个孩子的预订。

【讨论】:

    【解决方案2】:

    终于找到了解决这个问题的办法

    解决这个问题的正确方法是

    建立两个关系

    然后使用 where 条件更改代码以确保它根据预订值传递正确的关系

    但是因为这种修复方式需要大量代码更改,我尝试寻找其他方式

    其他方法是创建一个名为“primary_booking_id”的列,而不是创建“parent_booking_id”

    此“primary_booking_id”将始终包含第一次预订的 booking_id

    所以在第一次创建模型时,我将更新它以获得 booking_id

    $booking->update(['primary_booking_id' => $booking->id]);
    

    然后在创建它的孩子的过程中,我会将primary_booking_id放入创建中

    $input['primary_booking_id'] => $previous_booking->primary_booking_id;
    
    $booking::create($input);
    

    因此处理方式只需对预订交易关系函数进行微小的更改,如下所示

    public function transaction()
    {
            return $this->hasOne('App\Models\Transaction', 'booking_id', 'primary_booking_id');
    }
    

    瞧!

    它可以工作,没有重大变化

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-13
      • 2017-07-26
      • 1970-01-01
      • 2016-10-29
      • 2015-11-25
      • 2020-10-26
      • 2014-08-17
      • 2015-12-09
      相关资源
      最近更新 更多