加载具有条件递归的多态模型

时间:2016-03-03 19:38:53

标签: mysql laravel-5 laravel-5.2

我试图加载一个多态模型,其中某些条件与其他两个模型相关并且存在一些问题。

我的模特:

class One extends Model {

    public function twos() {
        return $this->hasMany(Two::class);
    }

    public function threes() {
        return $this->morphMany(Three::class, 'threeable');
    }
}


class Two extends Model {

    public function one() {
        return $this->belongsTo(One::class);
    }

    public function threes() {
        return $this->morphMany(Three::class, 'threeable');
    }
}

class Three extends Model {

    public function threeable() {
        return $this->morphTo();
    }
}

到目前为止,每件事都很棒:我有很多One个项目,它们有很多Two个关系,并且两个关系都有Three个关系(单独)。

现在我尝试从Three获取最新的Two,它也可以来自One关系(来自A或B的最高threes.updated_at)。

threes 表看起来像这样

| id | threeable_id | threeable_type | updated_at |
|---|---|---|---|
| 1 | 1 | A | 1 |
| 2 | 1 | A | 2 |
| 3 | 1 | B | 3 |
| 4 | 1 | B | 4 |
| 5 | 2 | A | 2 |
| 6 | 2 | A | 4 |
| 7 | 2 | B | 1 |
| 8 | 2 | B | 3 |

我希望B::find(1)->withC()的threes.id = 4和B::find(2)->withC()的threes.id = 6。

出于性能原因,我想在一个查询中加载它(我正在加载多个Two并希望相关的Three并且不想为此激活自己的查询。所以我试着把它放在一个范围内(在班级Two中)。加入Three表并在子查询中对updated_at做了一些最大化...这是一个完全混乱,并没有那么好用

它并没有真正感受到“Laravel-way”:(

感谢您的帮助

修改

也许作为一个补充,这里是纯SQL

SELECT twos.id, threes.id
FROM
(SELECT
    twos.id twoId, MAX(th.updated_at) threeMaxUA
FROM
    twos

LEFT JOIN (SELECT
    th.*
FROM
    (SELECT
        threeable_id, threeable_type, MAX(updated_at) AS updated_at
    FROM
        threes
    WHERE
        deleted_at IS NULL
    GROUP BY threeable_id , threeable_type) thmax
        LEFT JOIN
    threes pr ON (th.threeable_id = thmax.threeable_id
        AND th.updated_at = thmax.updated_at
        AND th.threeable_type = thmax.threeable_type)
GROUP BY th.threeable_id , th.threeable_type) th

ON
(
    (th.threeable_id = twos.id AND th.threeable_type = 'App\\Two')
        OR
    (th.threeable_id = twos.product_id AND th.threeable_type = 'App\\One')
)

GROUP BY twos.id
) twthmax

LEFT JOIN twos ON twos.id = twthmax.twoId

LEFT JOIN threes ON (
    twthmax.threeMaxUA = threes.updated_at
    AND 
    (
        (threes.threeable_id = twos.id AND threes.threeable_type = 'App\\Two')
            OR
        (threes.threeable_id = twos.product_id AND threes.threeable_type = 'App\\One')
    )
)

0 个答案:

没有答案