我正在寻找以下方法:
假设我们有一个剧院应用程序,我们有三个模型:活动,会话和座位一方面评价另一方面。
我们有一个morphToMany关系,因此Rate可以与其他三个模型相关联。
现在,我们希望在每个模型中都有一个rate()关系,它实现了级联模式。如果我们要求Seat实例上的rates(),它将返回其费率,否则,它将检查会话是否有费率并将返回它们。如果没有,它将返回与事件相关的费率。
因此我们希望定义为层次结构或级联模式来检索费率。
修改
更多信息: 此外,棘手的部分是,例如,一个事件可能有两个费率:一般和青年50美元和30美元。但是一个特定的会话可能会有40美元一般。所以对于这个给定的会话,rates()方法应该返回两个费率:一般为40美元,青少年为30美元,因为它不是"覆盖"在Session实例中。
如果Session->rates()
是null
,那么我很容易返回$this->event->rates()
,但是当我想要应用这个" cascades"之前解释过
编辑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']);
}
}
和
<?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();
}
}
所以我正在尝试最简单的情况。会话没有费率,必须从其活动中获取。
我有一个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'
注意WHERE条件: WHERE assignated_rates
。assignated_rate_id
in(&#39; 2&#39;)其中2是会话的ID,而不是事件的ID与会话有关。
可能是个错误吗?或者我错过了什么?我想条件应该被限制为ID = 1,因为它是事件的ID
你会怎么做?
谢谢!
答案 0 :(得分:0)
如果可以保证所有席位都属于会议的一部分,并且可以保证所有会议都属于事件的一部分,那么继承可能很适合您。但是,就我个人而言,当我看到由潜在的顶级实体(尽管有框架类)构成的超过两个层次的类层次结构时,我开始感到怀疑。通常,可以通过组成关系更彻底地解决问题。
不过这只是预感,因此,如果您表现良好,请不要浪费我的时间。但是,如果在任何用例中将这些概念解耦会更加简洁,我会看到几种方法来实现。
一个是策略模式,在该模式中,您拥有一种主Rate类别,该类别评估请求的情况并确定适合从中提取利率的来源。另一个是Decorator模式,在该模式中,您可以将一种速率计算的结果反馈到另一种速率计算中以进行更改。 (这对于申请折扣可能很方便。)我认为我要考虑的就是责任链。这采用类似于中间件的“处理程序堆栈”的形式,并且其中的每个步骤都可以决定是否要应用来自特定来源的费率。
在任何情况下,直接在Model结构中解决此问题都是不正确的地方。在我看来,应该将它们视为静态配置,而不是静态配置,使关系 options 可用,但除了转换之外,实际上不对输出做出任何决定。