2

私は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()
4

2 に答える 2

1

私はあなたの例を再作成し、次のようにコードを変更しました:

$student = $this->add('Model_Student')->loadAny();
$student_detail= $this->add('Model_Class');
$student_detail->join('class_has_student.class_idclass','idclass')->addField('student_idstudent');
$student_detail->addCondition('student_idstudent',$student->id);
$ClassList = $view->add('StudentClasses', null, 'ClassList');

$view->setModel( $student );
$ClassList->setModel( $student_detail->debug() );

基本的には、表示したいモデルから始める必要があります。クラスを一覧表示するため、Model_Classを選択する必要があります。次に、モデルを多対多のテーブルと結合し、もう一方の端(student_idstudent)からフィールドを定義します。次に、状態で使用できます。

ここに画像の説明を入力してください

また、hasOne()の4番目の引数が逆参照フィールドを定義できるようにModel_Tableにパッチを適用する必要があったため、最新のATK4に更新してください。

https://github.com/atk4/atk4-testsuite/commit/ccaef2c5e5841bb265001f00d832c3583a4cf722

于 2012-10-12T01:06:00.010 に答える
0

このビデオはあなたの問題に対処する方法を説明していると思います:

http://www.youtube.com/watch?v=yghw7MZABPk&feature=plcp

最も効率的な方法で。

于 2012-09-18T19:30:20.323 に答える