Laravel ORM调用范围函数关系

时间:2014-04-08 17:37:26

标签: php orm laravel eloquent

我正在尝试将客户表中的关系加载到我的订单表中,但每次尝试时我都会收到此错误:

  

Symfony \ Component \ Debug \ Exception \ FatalErrorException   在非对象上调用成员函数where()

这是我的订单模型

class Orders extends Eloquent
{
    protected $softDelete = true;

    public function order_items()
    {
        return $this->hasMany('Order_item');
    }

    public function customer()
    {
        return $this->hasOne('Customer', 'id', 'customer_id');
    }

    public function client()
    {
        return $this->hasOne('Client', 'id', 'client_id');
    }

    public function billingAddress()
    {
        if($this->client()->first() != null)
        {
            return $this->client()->getBillingAddress($this->billing_address_id);
        }
        else
        {
            return $this->customer()->getBillingAddress($this->billing_address_id);
        }
    }
}

这是我的客户模型

class Customer extends Eloquent
{
    protected $softDelete = true;

    public function order()
    {
        $this->belongsTo('Orders');
    }

    public function addresses()
    {
        $this->hasMany('Customeraddress', 'id', 'customer_id');
    }

    public function scopeGetBillingAddress($query, $addressId)
    {
        return $this->addresses()
                    ->where('id', '=', $addressId)
                    ->where('type', '=', 'billing');
    }

    public function scopeGetShippingAddress($query, $addressId)
    {
        return $this->addresses()
                    ->where('id', '=', $addressId)
                    ->where('type', '=', 'shipping');
    }
}

最后这是我的客户模型:

class Customeraddress extends Eloquent
{
    protected $table = "customer_addresses";
    protected $softDelete = true;

    public function customer()
    {
        $this->belongsTo('Customer');
    }
}

现在我正在尝试在我的控制器上运行此命令以获取订单地址,但我一直收到错误。我怎么能通过Eloquent关系和范围函数来做到这一点?

$address = Orders::find(21)->billingAddress()->first();
echo $address->street;

1 个答案:

答案 0 :(得分:1)

更改此内容:

public function addresses()
{
    // $this->hasMany('Customeraddress', 'id', 'customer_id'); // wrong order of keys
    return $this->hasMany('Customeraddress', 'customer_id', 'id');
}

和这两个

// edit: Order is a child of customer and client so:
public function customer()
{
    //return $this->hasOne('Customer', 'customer_id', 'id');
    return $this->belongsTo('Customer', 'customer_id', 'id'); // customer_id and id are redundant bu I leave it for clarity
}

public function client()
{
    //return $this->hasOne('Client', 'client_id', 'id');
    return $this->belongsTo('Client', 'client_id', 'id'); // same here
}

顺便说一下,这个很危险:)

public function billingAddress()
{
    // This line results in db query everytime you call billingAddress 
    // Unless you cache the query, it's overkill
    if($this->client()->first() != null)

    // instead use:
    if($this->client != null)

    {
        return $this->client()->getBillingAddress($this->billing_address_id);
    }
    else
    {
        return $this->customer()->getBillingAddress($this->billing_address_id);
    }
}

将范围更改为访问者:

public function getBillingAddressAttribute($addressId)
{
    return $this->addresses()
                ->where('id', '=', $addressId)
                ->where('type', '=', 'billing')->first();
}

public function getShippingAddressAttribute($addressId)
{
    return $this->addresses()
                ->where('id', '=', $addressId)
                ->where('type', '=', 'shipping')->first();
}

// then you can call it like $customer->shippingAddress etc