laravel 获取模型所属属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22060984/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:06:33  来源:igfitidea点击:

getting model belongsTo attributes

laravellaravel-4

提问by Zayin Krige

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;
    }
}

$coupon->pricegives me this error:-

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

LogicException Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation

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

However, $coupon->batch->priceworks just fine.

但是,$coupon->batch->price效果很好。

What am I missing?

我错过了什么?

回答by alexrussell

Your issue here is that you define a non-relationship method price()but you call it as if it was a relationship method (i.e. you call it as a property and not as a method).

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

The code you should be using to get the Coupon's price is:

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

$coupon->price();

The reason the relationship thing works (i.e. $coupon->batchover $coupon->batch()) is that Laravel has some special logic in - basically it catches you trying to access a property (->batchin this case) and checked to see if there's a corresponding method (->batch()). If there is one, it calls it and expects it to return a relationship, and then it calls ->first()of ->get()on that relationship depending on whether it's a single-result or a multiple-result relationship.

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

So what's happening in your code here is that you call $coupon->priceand Laravel, behind the scenes, decides that being as there's a ->price()method it must be a relationship. It calls the method, checks that it returns one of the Laravel relationship types, and when it doesn't, throws that LogicException.

所以在你的代码中发生的事情是你调用$coupon->price和 Laravel,在幕后,决定存在一个->price()方法,它必须是一个关系。它调用该方法,检查它是否返回 Laravel 关系类型之一,如果没有,则抛出那个LogicException

The general rules of thumb is this:

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

  • If you want an actual property (i.e. anything defined on the table) or the results of a relationship query, use property access
  • If you want anything else (i.e. behaviour you're defined using a method) you must call the method directly
  • 如果您想要实际属性(即表中定义的任何内容)或关系查询的结果,请使用属性访问
  • 如果您想要其他任何东西(即您使用方法定义的行为),您必须直接调用该方法

Also, sometimes there is a good reason to call a relationship as the method rather than the property - calling the method returns something you can add query builder constraints on to, whereas calling the property gets you all the results. So say Coupons can be enabled or disabled (for example), the following holds:

此外,有时有一个很好的理由将关系作为方法而不是属性来调用 - 调用该方法会返回一些您可以添加查询构建器约束的内容,而调用该属性会为您提供所有结果。所以说Coupons 可以启用或禁用(例如),以下内容成立:

  • $batch->couponsgets you all coupons that the batch has
  • $batch->coupons()->whereEnabled(1)->get()gets you all enabled coupons for a given batch
  • $batch->coupons()->orderBy('order')->get()gets you all the coupons that the batch has, ordered by a field called order
  • $coupon->batchgets you the given coupon's batch
  • $batch->coupons为您提供该批次的所有优惠券
  • $batch->coupons()->whereEnabled(1)->get()为您提供给定批次的所有启用优惠券
  • $batch->coupons()->orderBy('order')->get()为您提供该批次的所有优惠券,由名为的字段订购 order
  • $coupon->batch为您提供给定的优惠券批次

Hopefully that explains the difference between Eloquent's use of methods versus properties for relationships, and why all augmented behaviour (like price on coupon in your example, but notprice on batch, which is inherent behaviour) must be called as a method.

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

回答by Sturm

Take a moment to realize what objects you actually have here.

花点时间了解一下您实际拥有的物品。

When you call $this->batch;you're no longer chaining the relationship queries - you've actually retrieved the information from the database already. In order to define that query you'd have to do it one of several ways including:

当您打电话时,$this->batch;您不再链接关系查询——您实际上已经从数据库中检索了信息。为了定义该查询,您必须使用以下几种方法之一进行操作:

Coupon::with('batch.price')->get();

You could of course do it with relationships but it's late and I'm not sure where exactly Price belongs in the scheme of this since I don't see a method for it associated with batch. Presumably you could do:

你当然可以用关系来做,但已经晚了,我不确定价格在这个方案中的确切位置,因为我没有看到与批处理相关的方法。想必你可以这样做:

public function price()
{
    return $this->batch->price;
}

if Price is a derivative of Batch.

如果 Price 是 Batch 的衍生物。