私はATKの学生登録の例/チュートリアルに取り組んでおり、テーブルのリンクを介したref()の使用に固執しています。
システムの基本的なERは次のとおりです。
[Student] ||---|< [class_has_student] >|---|| [class] >|----|| [subject]
サブジェクトには、サブジェクト名、サブジェクトコード、実行できる学期、および説明が格納されます。クラスは、特定の期間にわたって特定の科目について学生に提供される講義/チュートリアルです。学生はクラスに登録でき、リレーションはclass_has_studentテーブルに保存されます。
基本的な例として、特定の学生の詳細と、彼らが登録されているクラス(科目名)を表示したいと思います。ビューテンプレートを使用して、学生の詳細(名前など)とクラス(科目名)を表示しています。 )Listerクラスを使用して登録されます。主な問題は、特定の学生が使用して登録されている科目を一覧表示しようとする場合です。
$student_detail= $student->ref('ClassHasStudent2')->ref('class_idclass')
学生が登録されているすべての科目を取得するのではなく、DBからすべての科目を取得します。
この例のページ、モデル、テンプレートコード、およびそれを機能させるために変更された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 |
+---------+-------------------+------------+------------+--------------+
class.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 |
+-----------+------------+--------+
student.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. |
+-----------+-----------+--------------+----------+--------------------------+
subject.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 );
}
}
また、dereferenced_field変数を設定できるTable::hasOne()
次のように変更しました。hasOne
/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
上記の例をビデオで指定されたデザインに変更すると、次のコードが生成されます。
student.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_idではなくstudent_idstudentについて文句を言う以外は、エラーは同じです。
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()