我一直在研究ATK的学生注册示例/教程,并且一直坚持通过链接表使用 ref()。
系统的基本 ER 如下:
[Student] ||---|< [class_has_student] >|---|| [class] >|----|| [subject]
主题存储主题名称、主题代码、可以运行的学期以及描述的位置。课程是在给定时期内针对给定主题提供给学生的讲座/教程。学生可以注册一个班级,并且关系存储在 class_has_student 表中。
对于基本示例,我希望显示特定学生的详细信息并显示他们注册的课程(带有学科名称)。我正在使用视图模板来显示学生详细信息(姓名等)和任何课程(带有学科名称) 他们使用 Lister 类注册。主要问题是在尝试列出特定学生注册的科目时使用:
$student_detail= $student->ref('ClassHasStudent2')->ref('class_idclass')
它不是检索学生注册的所有科目,而是从数据库中检索所有科目。
请参阅下面的页面、模型和此示例的模板代码,以及修改后的 Table.php 类以使其工作(对不起,长度)。
谢谢你的帮助。
楷模
“类”表
+-------------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------+------+-----+---------+----------------+
| idclass | int(11) | NO | PRI | NULL | auto_increment |
| subject_idsubject | int(11) | NO | MUL | NULL | |
| date_start | date | YES | | NULL | |
| date_end | date | YES | | NULL | |
| max_students | int(11) | YES | | NULL | |
+-------------------+---------+------+-----+---------+----------------+
select * from class;
+---------+-------------------+------------+------------+--------------+
| idclass | subject_idsubject | date_start | date_end | max_students |
+---------+-------------------+------------+------------+--------------+
| 1 | 2 | 2012-09-10 | 2012-09-30 | 10 |
| 2 | 1 | 2012-09-08 | 2012-09-30 | 30 |
| 3 | 3 | 2012-10-01 | 2012-10-31 | 35 |
| 4 | 2 | 2012-09-19 | 2012-09-29 | 10 |
+---------+-------------------+------------+------------+--------------+
类.php
<?php
class Model_Class extends Model_Table {
public $table='class';
public $entity_code='class';
public $id_field='idclass';
function init(){
parent::init();
$this->hasOne('Subject','subject_idsubject','name', 'subject_name');
$this->addField('date_start')->type('date')->caption('Start');
$this->addField('date_end')->type('date')->caption('End');
$this->addField('max_students')->type('int');
$this->hasMany('ClassHasStudent','class_idclass', 'idclass');
}
}
“学生”表
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| idstudent | int(11) | NO | PRI | NULL | auto_increment |
| student_id | varchar(45) | NO | | NULL | |
| name | varchar(45) | NO | | NULL | |
+------------+-------------+------+-----+---------+----------------+
select * from student;
+-----------+------------+--------+
| idstudent | student_id | name |
+-----------+------------+--------+
| 1 | T123 | Tom |
| 2 | L222 | Lizley |
| 3 | B123 | Betty |
| 4 | H33 | Homer |
| 5 | N42 | Nick |
+-----------+------------+--------+
学生.php
<?php
class Model_Student extends Model_Table {
public $table='student';
public $entity_code='student';
public $id_field='idstudent';
public $title_field='name';
function init(){
parent::init();
$this->addField('student_id')->caption('Student ID');
$this->addField('name')->caption('Name');
$this->hasMany('ClassHasStudent', 'student_idstudent', 'idstudent');
}
}
Mysql“class_has_student”表
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| idclass_has_student | int(11) | NO | PRI | NULL | auto_increment |
| class_idclass | int(11) | NO | MUL | NULL | |
| student_idstudent | int(11) | NO | MUL | NULL | |
| date_enrolled | varchar(45) | YES | | NULL | |
| grade | double | YES | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
select * from class_has_student;
+---------------------+---------------+-------------------+---------------+-------+
| idclass_has_student | class_idclass | student_idstudent | date_enrolled | grade |
+---------------------+---------------+-------------------+---------------+-------+
| 1 | 1 | 1 | 2012-09-04 | 0 |
| 2 | 1 | 2 | 2012-09-11 | 0 |
| 3 | 2 | 1 | 2012-09-14 | 0 |
+---------------------+---------------+-------------------+---------------+-------+
classhasstudent.php
<?php
class Model_ClassHasStudent extends Model_Table {
public $table='class_has_student';
public $entity_code='class_has_student';
public $id_field='idclass_has_student';
function init(){
parent::init();
$this->hasOne('Class','class_idclass','idclass', 'class_name');
$this->hasOne('Student', 'student_idstudent', 'name', 'student_name');
$this->addField('date_enrolled')->type('date');
$this->addField('grade');
}
}
mysql“主题”表
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| idsubject | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(45) | YES | | NULL | |
| subject_code | varchar(45) | YES | | NULL | |
| semester | varchar(45) | YES | | NULL | |
| description | blob | YES | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
select * from subject;
+-----------+-----------+--------------+----------+--------------------------+
| idsubject | name | subject_code | semester | description |
+-----------+-----------+--------------+----------+--------------------------+
| 1 | Maths | mat101 | 1 | Mathematics and numbers. |
| 2 | English | enh101 | 1 | English and languages. |
| 3 | Chemistry | chm101 | 2 | Inorganic chemistry. |
+-----------+-----------+--------------+----------+--------------------------+
主题.php
<?php
class Model_Subject extends Model_Table {
public $entity_code='subject';
public $id_field='idsubject';
function init(){
parent::init();
$this->addField('name');
$this->addField('subject_code');
$this->addField('semester');
$this->addField('description');
}
}
李斯特
<?php
// Lister class for displaying classes that a student attends.
class StudentClasses extends Lister {
function init(){
parent::init();
}
// Override defaultTemplate function.
function defaultTemplate(){
return array('view/class_info');
}
}
模板
/templates/default/view/student_details.html
<div id="<?$_name?>" class="projectinfo">
<table class="student">
<tr><td id="property">Student Name</td><td id="value"> <?$name?> </td></tr>
<tr><td id="property">Student ID</td> <td id="value"><?$student_id?></td></tr>
</table>
</div>
<h2>Enrolled classes</h2>
<?ClassList?>
<?/?>
/templates/default/view/class_info.html
<dl id="<?$_name?>" class="<?$class?>">
<dt><?$subject_name?></dt>
<dd><?$date_start?></dd><dd><?$date_start?></dd>
</dl>
页面
<?php
class page_TestClasses extends Page {
function init() {
parent::init();
$this->api->auth->check();
$this->api->stickyGET('id');
}
// Called only once.
function initMainPage(){
$view=$this->add('View',null,null,array('view/student_details'));
// $student = $this->add('Model_Student')->loadAny();
$student = $this->add('Model_Student')->loadAny();
// $student_detail= $student->ref('ClassHasStudent')->debug();
// select `idclass_has_student`,`class_idclass`,(select `idclass` from `class` where `class_has_student`.`class_idclass` = `class`.`idclass` ) `class_idclass_2`,`student_idstudent`,(select `name` from `student` where `class_has_student`.`student_idstudent` = `student`.`idstudent` ) `student_name`,`date_enrolled`,`grade` from `class_has_student` where `class_has_student`.`student_idstudent` = "1"
+---------------------+---------------+-----------------+-------------------+--------------+---------------+-------+
| idclass_has_student | class_idclass | class_idclass_2 | student_idstudent | student_name | date_enrolled | grade |
+---------------------+---------------+-----------------+-------------------+--------------+---------------+-------+
| 1 | 1 | 1 | 1 | Tom | 2012-09-04 | 0 |
| 3 | 2 | 2 | 1 | Tom | 2012-09-14 | 0 |
+---------------------+---------------+-----------------+-------------------+--------------+---------------+-------+
// USING $this->hasOne('Class','class_idclass','idclass', 'class_name'); in ClassHasStudent
// select `idclass_has_student`,`class_idclass`,(select `idclass` from `class` where `class_has_student`.`class_idclass` = `class`.`idclass` ) `class_name`,`student_idstudent`,(select `name` from `student` where `class_has_student`.`student_idstudent` = `student`.`idstudent` ) `student_name`,`date_enrolled`,`grade` from `class_has_student` where `class_has_student`.`student_idstudent` = "1";
+---------------------+---------------+------------+-------------------+--------------+---------------+-------+
| idclass_has_student | class_idclass | class_name | student_idstudent | student_name | date_enrolled | grade |
+---------------------+---------------+------------+-------------------+--------------+---------------+-------+
| 1 | 1 | 1 | 1 | Tom | 2012-09-04 | 0 |
| 3 | 2 | 2 | 1 | Tom | 2012-09-14 | 0 |
+---------------------+---------------+------------+-------------------+--------------+---------------+-------+
$student_detail= $student->ref('ClassHasStudent')->ref('class_idclass')->debug();
// select `idclass`,`subject_idsubject`,(select `name` from `subject` where `class`.`subject_idsubject` = `subject`.`idsubject` ) `subject_idsubject_2`,`date_start`,`date_end`,`max_students` from `class`
+---------+-------------------+---------------------+------------+------------+--------------+
| idclass | subject_idsubject | subject_idsubject_2 | date_start | date_end | max_students |
+---------+-------------------+---------------------+------------+------------+--------------+
| 1 | 2 | English | 2012-09-10 | 2012-09-30 | 10 |
| 2 | 1 | Maths | 2012-09-08 | 2012-09-30 | 30 |
| 3 | 3 | Chemistry | 2012-10-01 | 2012-10-31 | 35 |
| 4 | 2 | English | 2012-09-19 | 2012-09-29 | 10 |
+---------+-------------------+---------------------+------------+------------+--------------+
// Add Lister object to view, using LibraryList template spot.
$ClassList = $view->add('StudentClasses', null, 'ClassList');
$view->setModel( $student );
$ClassList->setModel( $student_detail );
}
}
我也修改Table::hasOne()
为以下,哪里hasOne
可以设置dereferenced_field变量。/atk4/lib/Model/Table.php
/** Defines one to many association */
function hasOne($model,$our_field=null,$display_field=null,$deref_field_name=null){
if(!$our_field){
if(!is_object($model)){
$tmp=preg_replace('|^(.*/)?(.*)$|','\1Model_\2',$model);
$tmp=new $tmp; // avoid recursion
}else $tmp=$model;
$our_field=($tmp->table).'_id';
}
$r=$this->add('Field_Reference',$our_field);
$r->dereferenced_field=$deref_field_name;
$r->setModel($model,$display_field);
return $r;
}
更新 1
将上述示例更改为视频中指定的设计会生成以下代码:
学生.php
<?php
class Model_Student extends Model_Table {
public $table='student';
public $entity_code='student';
public $id_field='idstudent';
public $title_field='name';
function init(){
parent::init();
$this->addField('student_id')->caption('Student ID');
$this->addField('name')->caption('Name');
$this->hasMany('ClassJoinClassHasStudent');
}
}
ClassJoinClassHasStudent.php
class Model_ClassJoinClassHasStudent extends Model_Class {
function init(){
parent::init();
$chs = $this->join('class_has_student.class_idclass','idclass');
// Import fields from ClassHasStudent
$chs->addField('date_enrolled');
$chs->addField('grade');
$chs->hasOne('Class'); // use id_class from CHS table.
}
}
但是,我收到以下与在 ClassJoinClassHasStudent 中设置主字段相关的错误。我试过调用 hasMany('ClassJoinClassHasStudent', 'student_idstudent', 'idstudent'),但错误是一样的,只是它抱怨的是 student_idstudent 而不是 student_id。
BaseException
Child element not found
Additional information:
Raised by object: Object Model_ClassJoinClassHasStudent(studentenrol_testclasses_model_student_ClassJoinClassHasStudent_model_classjoinclasshasstudent)
element: student_id
Possible Actions:
Debug this Model
/home/user1/public_html/studentenrol/atk4/lib/BaseException.php:38
Stack trace:
/home/user1/public_html/studentenrol/atk4/lib/BaseException.php :38 BaseException BaseException->collectBasicData(Null, 1, 0)
/home/user1/public_html/studentenrol/atk4/lib/AbstractObject.php :292 BaseException BaseException->__construct("Child element not found")
/ : studentenrol_testclasses_model_student_ClassJoinClassHasStudent_model_classjoinclasshasstudent Model_ClassJoinClassHasStudent->exception("Child element not found")
/home/user1/public_html/studentenrol/atk4/lib/Model/Table.php :87 Loggercall_user_func_array(Array(2), Array(1))
/home/user1/public_html/studentenrol/atk4/lib/AbstractObject.php :202 studentenrol_testclasses_model_student_ClassJoinClassHasStudent_model_classjoinclasshasstudent Model_ClassJoinClassHasStudent->exception("Child element not found")
/home/user1/public_html/studentenrol/atk4/lib/Model/Table.php :259 studentenrol_testclasses_model_student_ClassJoinClassHasStudent_model_classjoinclasshasstudent Model_ClassJoinClassHasStudent->getElement("student_id")
/home/user1/public_html/studentenrol/atk4/lib/Model/Table.php :321 studentenrol_testclasses_model_student_ClassJoinClassHasStudent_model_classjoinclasshasstudent Model_ClassJoinClassHasStudent->addCondition("student_id", "1")
/home/user1/public_html/studentenrol/atk4/lib/SQL/Many.php :48 studentenrol_testclasses_model_student_ClassJoinClassHasStudent_model_classjoinclasshasstudent Model_ClassJoinClassHasStudent->setMasterField("student_id", "1")
/home/user1/public_html/studentenrol/atk4/lib/Model/Table.php :243 studentenrol_testclasses_model_student_ClassJoinClassHasStudent SQL_Many->ref(Null)
/home/user1/public_html/studentenrol/page/testclasses.php :93 studentenrol_testclasses_model_student Model_Student->ref("ClassJoinClassHasStudent")
/home/user1/public_html/studentenrol/atk4/lib/ApiFrontend.php :93 studentenrol_testclasses page_TestClasses->initMainPage()
/home/user1/public_html/studentenrol/atk4/lib/ApiWeb.php :332 studentenrol Frontend->layout_Content()
/home/user1/public_html/studentenrol/atk4/lib/ApiFrontend.php :33 studentenrol Frontend->addLayout("Content")
/home/user1/public_html/studentenrol/atk4/lib/ApiWeb.php :208 studentenrol Frontend->initLayout()
/home/user1/public_html/studentenrol/index.php :24 studentenrol Frontend->main()