所以我有一个与Laravel和模型继承有关的疯狂想法。我想配置一组具有单个父模型的模型,但是当我请求子模型时,我希望返回数据。例如,我将有一个Contacts模型,它是父模式:
Contacts: id, first_name, last_name, image
然后我会有一系列继承自Contacts的联系人类型。这些儿童模型中的每一个都有自己的一组领域(即,对于我们加入时需要知道的成员等,但对于志愿者,我可能需要知道他们是否拥有最新的急救证书)。以下是一些例子:
Members: contact_id, joined_on, birthday, medical_concerns
Volunteers: contact_id, current_first_aid, interests
Staff: contact_id, pay_rate
我希望能够做到这样的事情:
$members = \App\Member::all();
并返回联系人AND成员数据,好像所有内容都是一行,如下所示:
+---+------------+-----------+-------+------------+------------+------------------+
|id | first_name | last_name | image | joined_on | birthday | medical_concerns |
+---+------------+-----------+-------+------------+------------+------------------+
| 1 | Fred | Bloggs | null | 2015-01-01 | 1993-10-22 | false |
| 2 | Jim | Phillips | null | 2016-04-30 | 1987-09-22 | true |
+---+------------+-----------+-------+------------+------------+------------------+
为了让它变得更加困难,我希望所有适用于父母的关系都适合孩子。所以我可以这样做:
$members = \App\Member::find(1)->phone
而且,即使会员模型没有为Phone模型定义关系,它也会返回与联系人相关的电话,因为父母有这种关系。
我还希望能够在检索数据时指定不属于该子项的列,而不会让Laravel抛出错误:
$members = \App\Member::all(['first_name','last_name','joined_on'])
我已经搞砸了Eloquent模型并编写了我自己的all版本并找到了正在运行的方法,但看起来我可能必须覆盖所有方法才能使其工作,也许这会更多工作不只是放弃Eloquent并寻找其他(或我自己的定制)解决方案。
所以我想我的问题是:是否有一个简单的"用Laravel做这个的方法,还是我试图让它做一些从未打算过的事情?
答案 0 :(得分:0)
我认为你可以这样做:
$members = \App\Members::with('contact')->all();
当然,您的会员模型应该已经定义了联系模型的belongsTo关系。
答案 1 :(得分:0)
是否有"容易"用Laravel做这个的方法,还是我试图让它做一些从未打算过的事情?
是
Eloquent doen以这种方式管理继承。最好是实现polymorphic relations。
然而,压倒这一点似乎符合您的目的:
abstract class ContactSubclass extends Contact
{
protected $with = 'parent';
public function parent()
{
return $this->belongsTo(Contact::class, 'contact_id');
}
public function newQuery()
{
$contactTable = (new Contact())->getTable();
$thisTable = (new static())->getTable();
$builder = parent::newQuery();
$builder->join($contactTable, "$thisTable.contact_id", '=', "$contactTable.id");
return $builder;
}
public function newFromBuilder($attributes = [], $connection = null)
{
$model = parent::newFromBuilder($attributes, $connection);
if ($model->parent) {
$model->setRawAttributes(array_merge($model->parent->getAttributes(), $model->getAttributes()), true);
}
return $model;
}
protected function getRelationshipFromMethod($method)
{
if (method_exists(parent::class, $method)) {
return $this->parent->getRelationshipFromMethod($method);
}
return parent::getRelationshipFromMethod($method);
}
}
让Member
和其他子类扩展此类(或在扩展Contact
的每个类中添加这些覆盖)。
(我还没有对它进行彻底的测试,试一试。此外,这不会直接处理急切的负载;如果你想支持它,请尝试找到要覆盖的内容。)