而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显得很复杂。