使用雄辩关系而不调用 ->get()


Using Eloquent relations without calling ->get()

所以我有一个名为Pricetag的模型,它与Price有一对多关系。

我可以使用此功能从Pricetag获取所有prices

public function prices(){
    return $this->hasMany('App'Price');
}

并这样称呼它:$pricetag->prices;

这些都是非常基本的。当函数用作attribute时,Eloquent 会自动调用函数上的 ->get() 函数。

现在回答我的问题:

如果我希望能够通过调用->price而不调用其上的->first()来从价格标签中获取当前价格(作为价格对象,而不是价格集合(......我该怎么做呢?

我现在有以下代码:

public function price($date = null){
    if($date === null){
        $date = Carbon::now();
    }
    return $this->prices()->orderBy('date', 'DESC')->where('date', '<=', $date);
}

当像这样调用时$pricetag->price它会返回价格集合。

当像这样调用时$pricetag->price()->first()它返回第一个价格作为price对象。

如何获取它,以便在像属性一样调用对象时返回对象?或者这就是属性"语法"结束的地方,我只需要使用类似 ->getPrice()

编辑 找到一个干净的解决方案!

我做了一个叫做History的特征,看起来像这样:

namespace App'Traits;
use Carbon'Carbon;
    trait History {
        public $current_date = null;
        public function when($date){
            $this->current_date = $date;
            return $this;
        }
        public function getDateAttribute(){
            return $this->current_date === null ? Carbon::now() : $this->current_date;
        }
    }

这将允许我毫无障碍地调用当前价格的 $pricetag->price 属性。如果我想得到明天或昨天或任何时间的价格,我会这样称呼它$pricetag->when($date)->price

Model内需要日期进行过滤的函数可以调用$this->date

没有测试代码,但在您的Pricetag模型上尝试此操作:

 public function getPriceAttribute($value)
    {
        $date = Carbon::now();
        return $this->prices()->orderBy('date', 'DESC')->where('date', '<=', $date)->first();
    }

现在尝试调用$pricetag->price 。让我知道你得到了什么。

将参数与关系方法/属性一起使用是非常规的,但您应该能够像这样获得所需的逻辑:

public function price($date = null) {
    if ($date === null) {
        $date = Carbon::now();
    }
    return $this->hasOne('App'Price')->orderBy('date', 'DESC')->where('date', '<=', $date);
}

通过将其定义为hasOne,该属性将返回对象,而不是集合。当您访问该属性时,您将始终获得最新价格(因为您无法传入参数(,但如果您使用关系方法,则可以传入要限制的日期:

// latest price
$price = $pricetag->price;
// other price
$otherPrice = $pricetag->price($someDate)->first();