而Customer对应的customers表中,会有shipping_address_id这个外键指向shipping_addresses表中的id。
那么我们要输出顾客和送货地址,我们需要先在model中定义好relationship:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
public function shippingAddress()
{
return $this->belongsTo(ShippingAddress::class);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ShippingAddress extends Model
{
public function country()
{
return $this->belongsTo(Country::class);
}
public function province()
{
return $this->belongsTo(Province::class);
}
public function city()
{
return $this->belongsTo(City::class);
}
}
在我们的控制器中,我们拉取出所有客户:
<?php
namespace App\Http\Controllers;
use App\Customer;
use App\Http\Controllers\Controller;
class CustomerController extends Controller
{
/**
* Simple function to fetch all customers with their shipping addresses
*
* @return String
*/
public function index()
{
$customers = Customer::with(['shippingAddress', 'shippingAddress.country', 'shippingAddress.province', 'shippingAddress.city'])->get();
//这里可以直接返回Eloquent Collections或Objects,toJson()将自动被调用
return $customers;
}
}
那么输出的JSON将会包含了多个层级的关系,那么在我们前端调用的时候,将会非常麻烦,因为我们需要一层一层剥开Object关系。
但是如果你熟悉Laravel,你可能会说,慢着!这个情况我可以用accessor不就完事儿了吗?
是的,我们确实可以使用accessor来简化我们的数据层级:
/**
* Get the customer's full shipping address
*
* @return string
*/
public function getFullShippingAddressAttribute()
{
return "{$this->shippingAddress->country->name} {$this->shippingAddress->province->name} {$this->shippingAddress->city->name} {$this->shippingAddress->address}";
}
但是我们还需要一步操作。由于customers这张表本身没有full_shipping_address这个字段,要使我们的JSON输出包含full_shipping_address,我们需要添加$appends数组:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = ['full_shipping_address'];
}
对于每一个我们想自定义的JSON字段,我们都需要进行上面两部的操作。这样一来其实非常麻烦,并且不利于代码的维护,因为这会让原本简洁的model显得很复杂。
