后端列表:按HasMany关系中的字段排序和筛选
我有两个与戏剧制作及其表演相关的模特:
class Play extends Model
{
...
public $table = 'johar_theater_plays';
public $hasMany = ['playtimes' => 'joharTheaterModelsPlayTime'];
}
class PlayTime extends Model
{
...
public $table = 'johar_theater_plays_times';
public $belongsTo = ['play' => ['joharTheaterModelsPlay']];
}
我将通过play
表格中的关系管理器管理播放时间。
要在play
-列表中显示playtimes
,我发现有两种可能性:
playtimes:
relation: playtimes
select: time
type: myRenderFunction
playtimes:
type: myRenderFunction
sortable: true
第一种类型使用$value
中的集合调用我的函数,第二种类型使用JSON字符串。
在第二种类型中,我可以按播放时间排序——它可能只是对JSON字符串进行排序,但这没关系
但我没有办法创建一个过滤范围来过滤掉今天之后所有没有表现的剧本我试过
scope:
condition: playtimes.time > now()
以及imho所有可能的变体。以及创建一个范围函数,我在其中修改了不同的where子句。问题总是SQL将JOIN放入group_concat:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'time' in 'where clause'
(SQL: select `johar_theater_plays`.*,
(select group_concat(time separator ', ')
from `johar_theater_plays_times`
where `johar_theater_plays_times`.`play_id` = `johar_theater_plays`.`id`)
as `playtimes`
from `johar_theater_plays`
where `time` > 2016-12-12 00:00:00
order by `playtimes` desc)" on line 662 of E:..IlluminateDatabaseConnection.php
因此,简短的问题是:当Play
具有许多Playtimes
时,我如何在播放列表中按播放时间.time(或FIRST(播放时间.times))进行筛选和排序
我找到了解决方案。如果有人有一个更漂亮的,我会很高兴,但现在我将使用这个范围功能:
public function scopeFutureonly($query)
{
$table = 'johar_theater_plays_times';
if(!$this->is_scoped) {
$query->join($table, 'johar_theater_plays.id', '=', $table . '.play_id');
$query->groupBy($table . '.play_id');
$query->where($table . '.time', '>', date("Y-m-d H:i:s"));
}
$this->is_scoped = true;
}
isScoped
是模型中的一个受保护变量,用于防止在多次调用作用域时多次添加查询。(感谢这里的planetadeleste)。
唯一的问题是,我在SQL中得到了两个JOIN:一个在concat中,一个在regular中。我认为只有完全手工创建SQL才能避免这种情况,这将违背十月的目的。。。。