Php 作用域函数中的Laravel ORM调用关系

Php 作用域函数中的Laravel ORM调用关系,php,orm,laravel,eloquent,Php,Orm,Laravel,Eloquent,我正在尝试将客户表中的关系加载到订单表中,但每次尝试都会出现以下错误: Symfony\Component\Debug\Exception\FatalErrorException 对非对象调用成员函数where() 这是我的订单模型 class Orders extends Eloquent { protected $softDelete = true; public function order_items() { return $this->h

我正在尝试将客户表中的关系加载到订单表中,但每次尝试都会出现以下错误:

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');
    }
}
最后是我的customeraddress模型:

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

    public function customer()
    {
        $this->belongsTo('Customer');
    }
}
现在,我试图在我的控制器上运行此命令以获取订单地址,但我不断收到错误。我怎样才能通过雄辩的关系和范围功能做到这一点

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

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

谢谢你的回复。我明白你在billingAddress中调用第一个()的意思,我已经删除了它。但是如果我像你说的那样交换密钥,我仍然有一个问题,我现在得到了这个错误:>SQLSTATE[42S22]:列未找到:1054未知列“clients.client\u id”在“where子句”中(SQL:select*from
clients
where
clients
deleted\u at为null并且
clients
client\u id=21限制1)通过前面的方法,我可以看到,当我调用$this->addresses()时,它返回的值就好像我调用了get()或first(),而我没有调用。不会让我在$this->addresses()显示您的客户和cients外键后堆叠。在哪里调用$this->addresses()?我的客户和客户没有外键,他们是父母。customeraddress和clientaddress已获得其各自父级的外键。因此,一个客户机会有许多Customeraddress,因此为什么会有许多(“Customeraddress”)。因此,从表的角度来看,customer\u address表有一个外键“customer\u id”,customer只有一个主键“id”。那么订单上的关系应该像我的编辑中那样颠倒。hasOne和belongsTo是方向相反的关系,因此,如果客户机有一个(或多个)SomeModel,那么SomeModel属于客户机,我建议坚持使用laravel命名约定,即:Model(单数)、ModelsController(复数)、modelstable(复数),因为这样可以更轻松地定义关系和其他许多事情
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