我有一个Activity
模型,它指的是Type
模型。
然后我有Schedule
模型,可以引用Activity
。
所以我可能想要根据活动 type 查询计划(可能是NULL,但这是无关紧要的;我只需要一个LEFT JOIN
而不是JOIN
.. )。
Laravel4的Eloquent允许我写一个 scoper (这里我想要一个负面 scoper)并写下
Schedule::where(...)->notOfType(myType)->...
试图与eager loading constraints一起使用太尴尬了
Schedule::with(array('activities' => function($query)
{
$query->where('activity_description', 'like', '%lots of lulz%');
}))->get();
...因为在这里我不会查询Activity
的属性,即Schedule
的直接相关模型,而是Type
的属性。我尝试了几个版本的嵌套with
s,然后转向好的'JOINs。
public function scopeNotOfType($query, $type) {
$query
->leftJoin('activities', 'schedule.activity_id', '=', 'activities.id')
->leftJoin('activity_types', 'activities.type_id', '=', 'activity_types.id')
->where('activity_types.name', '!=', $type->name);
}
表示根据activity_id将活动加入计划,然后将类型加入基于type_id的活动。此时,我的选择条件将在类型的名称字段上运行。
没有错误,对于非常非常简单的数据,它甚至可以工作,但随后仔细检查后发现数据都是错误的。执行查询和使用SQL分析器进行的简单(太简单!)检查发现返回了预期的数据,仅从Eloquent模型中消失。
第一个提示 - 好吧,更多的是牙齿 - 关于发生的事情是我的种子Schedule
,一旦被过滤器检索,似乎有一个描述字段“类型(1)说明“而不是预期的”时间表(1)说明“。
每当一个字段在多个模型中存在同名时,我就会从错误的模型中获取值,而不是从Schedule
获取。 阿哈。事实是Laravel4是PHP并按顺序检索SQL字段为,并且由于上面SELECT
生成的JOIN
是类似的,
+----------------+-------------+---------+-------------+
| schedule_id | description | type_id | description |
+----------------+-------------+---------+-------------+
| 1 | Sched_Desc | 1 | Type_Desc |
| 2 | Sched2_Desc | 7 | Type7_Desc |
+----------------+-------------+---------+-------------+
...当PDO驱动程序在第四列中检索字段值时,description
的 last 实例,类型的描述,覆盖第二个时间表的描述。
答案 0 :(得分:1)
显而易见的解决方案是只选择我需要的那些字段。从那以后,我一直在考虑Schedule
并且我对相关模型的关注度不高,我只是用Schedule
指定了select()
个字段:
public function scopeNotOfType($query, $type) {
$query
->leftJoin('activities', 'schedule.activity_id', '=', 'activities.id')
->leftJoin('activity_types', 'activities.type_id', '=', 'activity_types.id')
->select('schedule.*')
->where('activity_types.name', '!=', $type->name);
}
...而且,只检索Schedule
字段,不再有字段名称冲突。
另一个解决方案是在表字段中对表名进行编码,即有一个名为activity.activity_description
的字段,以便activity_description
不再与<something-else>_description
发生冲突;但这感觉更加尴尬,可能并不总是方便。