Laravel.morphToMany采用级联模式

spl*_*lig 9 php laravel eloquent

我正在寻找一种方法来做到以下几点:

假设我们有一个剧院应用程序,我们有三个模型:一方面是Event,SessionSeat,另一方面是Rate.

我们有一个morphToMany关系,因此Rate可以与其他三个模型相关联.

现在,我们希望在每个模型中都有一个rate()关系,它实现了级联模式.如果我们要求Seat实例上的rates(),它将返回其费率,否则,它将检查会话是否有费率并将返回它们.如果没有,它将返回与事件相关的费率.

因此,我们希望定义为层次结构或级联模式来检索速率.

编辑

更多信息:此外,棘手的部分是,例如,一个事件可能有两个费率:一般和青年50美元和30美元.但是一个特定的会话可能会有40美元一般.所以对于这个给定的Session,rates()方法应该返回两个速率:General为40 $,Youth为30 $,因为它没有在Session实例中"覆盖".

如果Session->rates()null很容易恢复$this->event->rates(),但不是那么容易的,当我想将此"瀑布"前解释

编辑2

在我第一次接近后,我看到一些奇怪的行为.为了简单起见:我上课了

<?php

namespace App;

use Backpack\CRUD\CrudTrait;
use Backpack\CRUD\ModelTraits\SpatieTranslatable\HasTranslations;
use Illuminate\Database\Eloquent\Model;

class Event extends Model
{

    public function rates()
    {               
        return $this->morphToMany('App\Rate', 'assignated_rate', 'assignated_rates', 'assignated_rate_id', 'rate_id')
                ->withPivot(['price', 'max_on_sale', 'max_per_inscription_set']);
    }

}
Run Code Online (Sandbox Code Playgroud)

<?php

namespace App;

use Backpack\CRUD\CrudTrait;
use Backpack\CRUD\ModelTraits\SpatieTranslatable\HasTranslations;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Session extends Model
{

    public function event()
    {
        return $this->belongsTo('App\Event');
    }

    public function rates()
    {            
        return $this->event->rates();
    }        
}
Run Code Online (Sandbox Code Playgroud)

所以我正在尝试最简单的情况.会话没有费率,必须从其活动中获取.

我有一个ID为2的会话和一个ID为1的事件.会话2属于事件1.

当我Session::find(2)->rates()返回Event1的比率时,但当我什么Session::find(2)->load('rates')也不做的时候返回.

如果我探索执行的查询,我得到:

SELECT `rates`.*, `assignated_rates`.`assignated_rate_id` as `pivot_assignated_rate_id`, [.....] FROM `rates` inner join `assignated_rates` on `rates`.`id` = `assignated_rates`.`rate_id` WHERE `assignated_rates`.`assignated_rate_id` in ('2') and `assignated_rates`.`assignated_rate_type` = 'App\\Event'
Run Code Online (Sandbox Code Playgroud)

注意WHERE条件:WHERE assignated_rates.assignated_rate_idin('2')其中2是Session的ID,而不是Session的相关事件.

可能是个bug吗?或者我错过了什么?我想条件应该被限制为ID = 1,因为它是事件的ID

你会怎么做?

谢谢!

Cla*_*ore 0

如果保证所有席位都属于会话的一部分,并且所有会话都保证属于活动的一部分,那么继承可能会很适合您。但就我个人而言,当我看到由潜在的顶级实体(尽管有框架类)组成的深度超过两层的类层次结构时,我开始感到怀疑。通常,通过组合关系可以更清晰地解决问题。

但这只是一种预感,所以如果你足够优秀,就不要让我浪费你的时间。但是,如果有任何用例将这些概念解耦会更简洁,我会看到几种方法可以做到这一点。

一种是策略模式,其中您有一种主费率类,用于评估请求的情况并确定适合从中获取费率的来源。另一种是装饰器模式,在这种模式中,您可以将一个费率计算的结果输入到另一个费率计算结果中进行更改。(这对于申请折扣可能很方便。)我认为我会选择责任链。这采用类似中间件的“处理程序堆栈”的形式,其中的每个步骤都可以决定是否要应用来自特定源的速率。

无论如何,直接在模型结构中解决这个问题并不是正确的选择。在我看来,它们应该被视为静态配置,使关系选项可用,但除了转换之外,实际上并不对输出做出任何决定。