获取模型归属于属性

Zay*_*ige 2 laravel laravel-4

class Batch extends Eloquent {
    public function coupons() {
        return $this->hasMany('Coupon');
    }
}

class Coupon extends Eloquent {
    public function batch() {
        return $this->belongsTo('Batch');
    }
    public function price() {
        $batch = $this->batch;
        return $batch->price;
    }
}
Run Code Online (Sandbox Code Playgroud)

$coupon->price 给我这个错误:

LogicException Relationship方法必须返回类型为Illuminate \ Database \ Eloquent \ Relations \ Relation的对象

但是,$coupon->batch->price工作正常。

我想念什么?

ale*_*ell 5

这里的问题是您定义了一个非关系方法,price()但您将其称为关系方法(即,将其称为属性而不是方法)来调用它。

您应该用来获取Coupon的价格的代码是:

$coupon->price();
Run Code Online (Sandbox Code Playgroud)

关系事物起作用的原因(即$coupon->batchover $coupon->batch())是Laravel具有一些特殊的逻辑-基本上,它会抓住您尝试访问属性的情况(->batch在这种情况下),并检查是否有相应的方法(->batch())。如果有一个,它调用它,期望它返回一个关系,然后它调用->first()->get()上的关系取决于它是否是一个单结果或多次结果的关系。

因此,您的代码中发生的事情是您调用$coupon->price了该代码,而Laravel在后台决定了存在,因为->price()它必须存在一种关系。它调用该方法,检查它是否返回Laravel关系类型之一,如果没有,则抛出该方法LogicException

一般的经验法则是这样的:

  • 如果要使用实际属性(即表上定义的任何内容)或关系查询的结果,请使用属性访问
  • 如果您还有其他需要(即使用方法定义的行为),则必须直接调用该方法

另外,有时有充分的理由将关系称为方法而不是属性-调用该方法将返回可以添加查询构建器约束的内容,而调用该属性将获得所有结果。所以说Coupons可以启用或禁用(例如),以下内容适用:

  • $batch->coupons 获取该批次具有的所有优惠券
  • $batch->coupons()->whereEnabled(1)->get() 获取给定批次的所有已启用优惠券
  • $batch->coupons()->orderBy('order')->get() 获取您批次拥有的所有优惠券,并通过名为 order
  • $coupon->batch 获取给定优惠券的批次

希望这解释了Eloquent使用方法与关系属性之间的区别,以及为什么必须将所有增强行为(例如,示例中的优惠券价格,而不是批量价格,这是固有的行为)称为一种方法。