0

我正在尝试获取所有访问者的列表,其中仅包含最新的访问信息和 API 调用的相关访问类型描述,我需要能够在一次查找中做到这一点。以前我们有下面的第二个代码块,但是当访问者有多个关联的访问记录(每个访问记录一个)时,这会返回访问者的多条记录。我只需要获取最新的(MAX(Visit.visit_date)但如果我们打算加入反对显然不能使用VisitType它)与它相关联VisitType.type_description

beforeFind() 函数在访问者模型上,因为我们试图获取访问者列表。

当我尝试使用下面的可包含代码时,我遇到了以下问题:

Warning (512): Model "Site" is not associated with model "Site" [CORE/Cake/Model/Behavior/ContainableBehavior.php, line 343]

Warning (512): Model "SubjectStatus" is not associated with model "SubjectStatus" [CORE/Cake/Model/Behavior/ContainableBehavior.php, line 343]

我建立了这些协会:

  • 访问者有很多访问,一次访问有一个访问者
  • 访客有一个站点,一个站点有许多访客
  • 访客状态有很多访客,访客属于访客状态
  • 访问 hasOne VisitKind, VisitKind hasMany Visits

失败的可包含代码:

  public function beforeFind($options, $primary=false) {
    if ($this->__AjaxDataLoad) {
      // Replacing a bunch of Model rebinds with Containable

      $this->Behaviors->load('Containable');

      $this->contain(array(
        'Site' => array(
          'conditions' => array('Site.id = Visit.site_id'),
          'field' => array('Site.site_name')
        ),
        ‘VisitorStatus' => array(
          'conditions' => array(‘VisitorStatus.id = Visitor.visit_status_id'),
          'field' => array(‘VisitorStatus.status')
        ),
        'Visit' => array(
          'conditions' => array('Visit.subject_id = Visitor.id'),
          'order' => 'Visit.visit_date DESC',
          'limit' => 1,
          'VisitType' => array(
            'conditions' => array('Visit.visit_type_id = VisitType.id'),
            'fields' => array('VisitType.type_description'),
          )
        )
      ));
    }
  }

以前,以下代码“有效”具有不良副作用,即每个访问者包含多行,每次访问一行:

  public function beforeFind($options, $primary=false) {
    if ($this->__AjaxDataLoad) {
      $this->unbindModelAll();
      $this->bindModel(array(
        'belongsTo' => array(
          'Site' => array(
            'className' => 'Site',
            'foreignKey' => 'site_id',
          ),
          ‘VisitorStatus' => array(
            'className' => ‘VisitorStatus',
            'foreignKey' => ‘visitor_status_id',
          )
        ),
        'hasOne' => array(
          'Visit' => array(
            'className' => 'Visit',
            'foreignKey' => ‘visitor_id',
            'order' => 'Visit.visit_date DESC’,
            ‘limit’ => 1 // <—————————————— THIS DOES NOTHING
          ),
          'VisitType => array(
            'foreignKey' => false,
            'conditions' => array("Visit.visit_type_id = VisitType.id"),
            'fields' => array('VisitType.type_description’)
          )
        )
      ));
    }
  }

我正在尝试的 Containable 结构有问题吗?

我已经配置 Debug = 2,CakePHP 版本 2.2.5

4

1 回答 1

0

我最终提出的解决方案完全绕过了 CakePHP 关系技术。它归结为使用 virtualFields 和子查询作为最后的手段。

  public function beforeFind($options) {
    if ($this->__AjaxDataLoad) {
      $options['joins'] = array(
        array(
          'table' => 'visits',
          'alias' => 'Visit',
          'type' => 'LEFT',
          'conditions' => array('Visit.visitor_id = Visitor.id')
        )
      );
      $options['group'] = array('Visitor.id');
      if (is_null($options['fields'])) {
        $options['fields'] = array(
          'Visitor.*', 'Site.*', 'VisitorStatus.*'
        );
      }
      $this->virtualFields['last_visit_date'] = 'MAX(Visit.visit_date)';
      $this->virtualFields['last_visit_kind'] = 'SELECT visit_kinds.kind FROM visits INNER JOIN visit_kinds ON visits.visit_kind_id = visit_kinds.id WHERE visits.visitor_id=Visitor.id ORDER BY visits.visit_date DESC LIMIT 1';
    }
    return $options;
  }
于 2014-01-23T06:14:16.087 回答