如何定义 hasMany 远关系

How to define a hasMany far relationship

假设你有

Facility  1------*  Section  1------*  Session  *------1  Event

也就是说,一个设施有很多部分;每个section可以开很多session;每个会话都属于一个事件。

我如何将其定义为 Facility 模型中的关系,以检索设施托管的 Event 的所有 唯一 实例?我试过这个:

class Facility extends Eloquent\Model {
    public function events() {
        return $this->hasMany('Event')
            ->join('session', 'session.event_id', '=', 'event.id')
            ->join('section', 'section.id', '=', 'session.section_id')
            ->join('facility', 'facility.id', '=', 'section.facility_id');
    }
}

我不知道我是否非常接近那个; Laravel 隐式添加约束 ("events"."facility_id" in (...)),一切都变得一团糟。

这样做的正确方法是什么?

我会避免在模型的关系方法中放置任何逻辑。而是使用 eloquent 来加载您的关系,一个接一个地加载或预先加载到 Facility 模型中。后者更可取。

class Facility extends Eloquent\Model 
{
    public function sections() 
    {
        return $this->hasMany('Section');
    }
}

只需确保每个模型都设置了正确的关系,这样您就可以链接预加载。如:

class Section extends Eloquent\Model 
{
    public function sessions() 
    {
        return $this->hasMany('Session');
    }
}

然后当你加载关系时,你可以使用点符号来预加载它们。

$facility = Facility::with('sections.sessions.event')->get();

$facility 现在将包含具有嵌套关系的 Facility 模型。您可以使用一些不同的数组助手来 extract/pluck 所有事件。

这离我最初的目标更近了:

我创建了一个 SQL 视图:

CREATE VIEW facility_events AS
  SELECT DISTINCT ON (e.id) e.id,
    e.name,
    e.created_at,
    e.updated_at,
    f.id AS facility_id
  FROM events e
    JOIN sessions s ON e.id = s.event_id
    JOIN sections_extended fse ON s.section_id = fse.id
    JOIN facilities f ON fse.root_facility_id = f.id;

然后我创建相应的 FactoryEvent Eloquent 模型,最后,在我的 class Facility:

public function events() {
    return $this->hasMany('App\FacilityEvent');
}

我期待看到 Laravel-only 解决方案。在其他框架中,比如 Yii,我已经能够做类似的事情而不需要直接在数据库上工作。