我有一个表帐户:
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中,我有我的Account模型:
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');
}
}
正如你所看到的,我在这里建立了一对一的关系。(当然,Address模型也有一个"belongsTo")。这一切都有效。
问题是,地址外键可以为null,因为帐户不需要地址。因此,如果我试图访问Account->地址,而它没有,我会得到一个"尝试访问非对象属性"错误。
如果帐户记录没有一个集合,我想做的是将Account->address设置为一个新的address对象(所有字段都为空)。
我所能做的就是在模型中创建第二种方法:
public function getAddress()
{
return empty($this->address) ? new Address() : $this->address;
}
或者,在飞行中添加它:
if (empty($account->address))
$account->address = new Address();
第一个解决方案非常接近,但我真的希望保留访问地址的功能,将其作为属性而不是方法。
所以,我的问题是:
如果账户->地址为空/null,我如何让账户->地址返回新地址()
哦,我试着覆盖$属性,比如:
protected $attributes = array
(
'address' => new Address()
);
但这就造成了一个错误。
使用访问器:
编辑:由于是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
方法中,或者覆盖Account 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);
}
您可以在单个访问器中完成所有这些操作,但这是它"应该"的样子。