我有一个表帐户:
act_id,
act_name,
act_address
我有一张桌子地址:
add_id,
add_street1,
<other fields you'd expect in an address table>
accounts.act_address是addresses.add_id的外键。在Laravel,我有我的账户模型:
use LaravelBook\Ardent\Ardent;
use Illuminate\Database\Eloquent\SoftDeletingTrait;
class Account extends Ardent
{
use SoftDeletingTrait;
protected $table = 'accounts';
protected $primaryKey = 'act_id';
public static $rules = array
(
'act_name' => 'required|unique:accounts'
);
protected $fillable = array
(
'act_name'
);
public function address()
{
return $this->hasOne('Address', 'add_id', 'act_address');
}
}
正如您所看到的,我在这里建立了一对一的关系。 (当然,地址模型也有'且属于'#)。一切正常。
问题是,地址外键可以为空,因为帐户不需要地址。因此,如果我尝试访问Account-&gt;地址时,如果没有,我会尝试访问非对象的属性&#39;错误。
我想要做的是将帐户 - >地址设置为新的地址对象(所有字段为空),如果帐户记录没有一套。
我能够做的是在模型中创建第二种方法:
public function getAddress()
{
return empty($this->address) ? new Address() : $this->address;
}
或者,即时添加:
if (empty($account->address))
$account->address = new Address();
第一个解决方案非常接近,但我真的希望将访问地址的功能保留为属性而不是方法。
所以,我的问题是:
如果Account-&gt;地址为空/ null,我如何才能使用Account-&gt;地址返回新的地址()?
哦,我尝试覆盖这样的$属性:
protected $attributes = array
(
'address' => new Address()
);
但这会引发错误。
答案 0 :(得分:3)
使用访问者:
编辑:由于belongsTo
不是hasOne
关系,因此有点棘手 - 您无法将模型与不存在的模型相关联,因为后者没有ID 强>:
public function getAddressAttribute()
{
if ( ! array_key_exists('address', $this->relations)) $this->load('address');
$address = ($this->getRelation('address')) ?: $this->getNewAddress();
return $address;
}
protected function getNewAddress()
{
$address = $this->address()->getRelated();
$this->setRelation('address', $address);
return $address;
}
但是,现在你需要这个:
$account->address->save();
$account->address()->associate($account->address);
这不是很方便。您也可以在getNewAddress
方法中保存新实例化的地址,或覆盖帐户save
方法,以自动进行关联。无论如何,对于这种关系,我不确定这样做是否有意义。对于hasOne
它会发挥得很好。
以下是hasOne
关系的显示方式:
public function getAddressAttribute()
{
if ( ! array_key_exists('address', $this->relations)) $this->load('address');
$address = ($this->getRelation('address')) ?: $this->getNewAddress();
return $address;
}
protected function getNewAddress()
{
$address = $this->address()->getRelated();
$this->associateNewAddress($address);
return $address;
}
protected function associateNewAddress($address)
{
$foreignKey = $this->address()->getPlainForeignKey();
$address->{$foreignKey} = $this->getKey();
$this->setRelation('address', $address);
}
你可以在单一存取器中完成所有这些,但这是它应该&#39;的方式。看起来像。