Zbi*_*woń 4 cakephp cakephp-3.0
假设我在CookBook中有完整的设置:http: //book.cakephp.org/3.0/en/orm/associations.html
class StudentsTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Courses', [
'through' => 'CourseMemberships',
]);
}
}
class CoursesTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Students', [
'through' => 'CourseMemberships',
]);
}
}
class CoursesMembershipsTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Students');
$this->belongsTo('Courses');
}
}
Student BelongsToMany Course
Course BelongsToMany Student
id | student_id | course_id | days_attended | grade
Run Code Online (Sandbox Code Playgroud)
我应该如何构建查询以查找给定学生的课程,他的成绩为=="A"?
$query = $this->Courses->find('all')
->contain(['CourseMemberships'])
->where(['CourseMemberships.student_id' => $student['id'], 'CourseMemberships.grade' => 'A']);
Run Code Online (Sandbox Code Playgroud)
这不行.我该怎么写呢?
ndm*_*ndm 19
通常你会使用匹配,但是ORM似乎不支持在连接表"关联"上匹配,因为它们在那时不是"真正的"关联(你可能想建议作为增强),它们正在稍后补充道.
matching() 解决方法什么工作是使用matching()和where()外部查询,即
$query = $this->Courses
->find('all')
// contain needs to use `Students` instead (the `CourseMemberships`
// data can be found in the `_joinData` property of the tag),
// or dropped alltogether in case you don't actually need that
// data in your results
->contain(['Students'])
// this will do the magic
->matching('Students')
->where([
'CourseMemberships.student_id' => $student['id'],
'CourseMemberships.grade' => 'A'
]);
Run Code Online (Sandbox Code Playgroud)
这将使用别名加入表students和courses_students连接表CourseMemberships,例如
INNER JOIN
students Students ON 1 = 1
INNER JOIN
courses_students CourseMemberships ON (
Courses.id = (CourseMemberships.course_id)
AND Students.id = (CourseMemberships.student_id)
)
Run Code Online (Sandbox Code Playgroud)
因此可以应用条件.这感觉就像一个不太好的解决方法.
另一种选择是添加另一个显式关联(如提到的那种@AtaboyJosef),即hasMany连接表的关联(这将在稍后的时间点自动完成,但正如已经提到的那样,为时已晚matching()).
请注意,这将需要命名连接表course_memberships!
class CoursesTable extends Table
{
public function initialize(array $config)
{
$this->belongsToMany('Students', [
'joinTable' => 'course_memberships',
'through' => 'CourseMemberships',
]);
$this->hasMany('CourseMemberships', [
'foreignKey' => 'course_id'
]);
}
}
Run Code Online (Sandbox Code Playgroud)
这样你就可以在CourseMemberships关联上使用匹配
$query = $this->Courses
->find('all')
// with this solution you can also use contain for `CourseMemberships`
->contain(['CourseMemberships'])
->matching('CourseMemberships', function(\Cake\ORM\Query $query) use ($student) {
return $query->where([
'CourseMemberships.student_id' => $student['id'],
'CourseMemberships.grade' => 'A'
]);
});
Run Code Online (Sandbox Code Playgroud)
应该创建一个类似的查询
INNER JOIN course_memberships CourseMemberships ON (
CourseMemberships.student_id = 1
AND CourseMemberships.grade = 'A'
AND Course.id = (CourseMemberships.course_id)
)
Run Code Online (Sandbox Code Playgroud)
这可能会更有效,因为它需要更少的选择.
| 归档时间: |
|
| 查看次数: |
12116 次 |
| 最近记录: |