如何定义 hasMany far 关系

Posted

技术标签:

【中文标题】如何定义 hasMany far 关系【英文标题】:How to define a hasMany far relationship 【发布时间】:2015-11-14 08:05:47 【问题描述】:

假设你有

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

即,一个设施有很多部分;每个部分可以举行多场会议;每个会话都属于一个事件。

如何将其定义为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 (...)),一切都搞砸了。

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

【问题讨论】:

来自 laravel 5.1 文档:Has Many Through “has-many-through”关系为通过中间关系访问远距离关系提供了便捷的捷径。例如,一个 Country 模型可能通过一个中间 User 模型有许多 Post 模型。在此示例中,您可以轻松收集给定国家/地区的所有博客文章。 laravel docs 我已经尝试过了,但在这种情况下,中间有两个关系。事实上,我已经实现了hasManyThrough 来获取会话。 很遗憾,hasManyThrough 只有 2 个级别。您必须为每个模型定义关系并执行此操作$events= Facility::with('sections.sessions.event')->get(); 【参考方案1】:

这离我最初的目标越来越近了:

我创建了一个 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 模型,最后在我的类中创建了Facility

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

我期待看到 Laravel 专用的解决方案。在其他框架中,例如 Yii,我已经能够做类似的事情,而无需直接处理数据库。

【讨论】:

【参考方案2】:

我会避免在模型的关系方法中添加任何逻辑。而是使用 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 模型。您可以使用一些不同的数组助手来提取/提取所有事件。

【讨论】:

当然这是我已经实现的选项。但是,正如我的问题所述,我希望这些事件有独特的结果。结果正在通过 REST API 使用,我无法为单个唯一事件发送数千个会话。我想要的是与给定设施相关的不同事件。 我追求的是能够做到Facility::with('events')。如果 Laravel 不允许我这样做,那么我会感到受到框架的限制,无论这是否是一个好的实践。

以上是关于如何定义 hasMany far 关系的主要内容,如果未能解决你的问题,请参考以下文章

model.hasMany 调用的东西不是 Sequelize.Model 的子类

当同一模型也存在 HasMany 关系时,如何更新 HasOne 关系?

Yii2 hasMany关系中如何在ON条件下使用常量

sequelizejs 关系/关联,hasMany/belongsTo vs 定义模型上的参考

Eloquent 自定义关系 hasMany(外域包含由外键连接的文本)

如何同步hasMany关系上的子表数据?