Php 在ATK中将ref()与链接表一起使用

Php 在ATK中将ref()与链接表一起使用,php,frameworks,atk4,Php,Frameworks,Atk4,我一直在为ATK编写学生注册示例/教程,我一直在通过链接表使用ref() 系统的基本ER如下所示: [Student] ||---|< [class_has_student] >|---|| [class] >|----|| [subject] 它不是检索学生注册的所有科目,而是从数据库检索所有科目 请参阅下面的页面、本例的模型和模板代码,以及修改后的Table.php类以使其正常工作(抱歉,篇幅太长) 谢谢你的帮助 型号 <?php class page_Test

我一直在为ATK编写学生注册示例/教程,我一直在通过链接表使用ref()

系统的基本ER如下所示:

[Student] ||---|< [class_has_student] >|---|| [class]  >|----|| [subject]
它不是检索学生注册的所有科目,而是从数据库检索所有科目

请参阅下面的页面、本例的模型和模板代码,以及修改后的Table.php类以使其正常工作(抱歉,篇幅太长)

谢谢你的帮助

型号

<?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 );

    }
}
“类”表

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');
    }
}
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');
      }
  }
  <?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');

      }

  }
  <?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');
      }
  }
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.
    }
}
classhastudent.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');
      }
  }
  <?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');

      }

  }
  <?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');
      }
  }
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.
    }
}
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');

      }

  }
更新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('ClassHasStudent', 'student_idstudent', 'idstudent');
      }
  }
  <?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');

      }

  }
  <?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');
      }
  }
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中设置master字段时出现了以下错误。我尝试调用hasMany('ClassJoinClassHasStudent','student\u idstudent','idstudent'),但错误是一样的,只是它抱怨student\u idstudent而不是student\u 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()

我认为这段视频解释了如何处理您的问题:


以最有效的方式。

我重新创建了您的示例,并更改了如下代码:

$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_类。然后将模型与多对多表联接,并从另一端(student_idstudent)定义字段。接下来,您可以在条件允许的情况下使用它

我还必须修补Model_表,以允许hasOne()的第四个参数定义取消引用的字段,因此请更新到最新的ATK4


谢谢罗马人,这个建议看起来很有用。这会在ATK2.4.2中吗?另外,您可以在页面类中使用refSQL()吗?使用上面的示例,在page_TestClass内部,我们将按如下方式使用:$student_detail=$student->refSQL('classHastudent/class_idclass')->debug();它可能会出现在4.2.3中。是的,您可以从任何地方调用该方法,但您必须记住,它返回的表达式在$student模型中可用。很高兴听到罗马语,谢谢您的帮助。同时,在ATK 4.2.1中是否有我的示例可以使用的变通方法?或者我们必须等待ATK 4.2.3?正如视频所解释的,你需要创建带有连接的模型,然后在hasMany中使用它-视频的第一部分解释了这一点,我确实说它与4.2一起工作。对不起,罗马人,我不应该半醒着看视频…错过了显而易见的。我已经用你们的视频教程修改了上面的例子。然而,我得到一个错误,请看上面。看起来是因为主键被弄乱了,因为我没有在每个表中使用默认的“id”。再次感谢。
$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() );