Почему условия в ассоциациях моделей не фильтруют результаты поиска в контроллере в CakePHP?

У меня две модели: Users и Lessons

  • User есть один Teacher
  • User принадлежит многим Students

Оба Teachers и Students являются Users

В моей модели Users у меня есть эта ассоциация:

public $hasMany = array(
    'Lesson' => array(
        'className' => 'Lesson',
        'foreignKey' => 'user_id',
        'dependent' => false,
    )
);

В моей модели Lessons в настоящее время у меня есть эта ассоциация:

public $belongsTo = array(
    'Teacher' => array(
        'className' => 'User',
        'foreignKey' => 'teacher_id',
        'conditions' => array('Teacher.group_id' => '2'),
        'fields' => '',
        'order' => ''
    )
);

Мои вопросы:

  1. Почему $teachers = $this->Lesson->Teacher->find('list'); возвращает все users, а не только teachers? Почему условия, установленные в belongsTo части модели, не фильтруют результаты, чтобы показать только Users с group_id из 2, т. е. Teachers? И если это не так, как это должно работать, то какой смысл ставить здесь условия?

    На данный момент я должен включать его в поиск каждый раз, что кажется излишним: $teachers = $this->Lesson->Teacher->find('list', array('conditions'=>array('Teacher.group_id'=>'2')))

  2. Как написать ассоциации для Students, чтобы у Lessons было много учеников? И как настроить для него базу данных?


person Chaim    schedule 19.10.2014    source источник
comment
Что касается части вашего вопроса о базе данных: вам нужно поделиться своими текущими таблицами (пользователи, учителя, ученики, уроки, пользователи_учителя и т. д.) и (как минимум) первичный и внешний ключи этой таблицы. Ваш вопрос сбивает с толку, потому что утверждение «У пользователей есть один учитель» подразумевает 2 таблицы из-за использования терминологии Cakephp. Но тогда ваше отношение ownTo в модели Lesson описывает учителей как подмножество таблицы User.   -  person AgRizzo    schedule 20.10.2014


Ответы (1)


1. Условие в вашей связи должно быть изменено, чтобы включить имя модели, а не псевдоним:

'conditions' => array('User.group_id' => 2),

2. Связь должна быть hasAndBelongsToMany (HABTM) может быть определен в вашей модели User следующим образом:

public $hasAndBelongsToMany = array(
    'Lessons' => array(
        'className' => 'Lesson',
        'joinTable' => 'lessons_users', // or the name from DB
        'foreignKey' => 'user_id',
        'associationForeignKey' => 'lesson_id',
        'unique' => 'keepExisting' // Set this based on your needs, check link above
    )
);

Учитывая приведенную выше связь, вам нужна новая таблица lessons_users в вашей базе данных для хранения данных об этой связи между учениками и уроками:

          +++++++++++++++++++++++++++++++++++++++++++++++++
          +  id (pk)  +  lesson_id (fk)  +  user_id (fk)  +
          +++++++++++++++++++++++++++++++++++++++++++++++++
          +     1     +         1        +        1       +
          +-----------+------------------+----------------+
          +     2     +         1        +        2       +
          +-----------+------------------+----------------+
          +     3     +         2        +        1       +
          +-----------+------------------+----------------+
          +     4     +         2        +        2       +
          +++++++++++++++++++++++++++++++++++++++++++++++++

Из примера выше; пользователь с идентификатором 1 берет уроки 1 и 2, а пользователь с идентификатором 2 также берет уроки 1 и 2. Аналогичным образом, на уроке с идентификатором 1 зарегистрированы пользователи с идентификаторами 1 и 2, а на уроке с идентификатором 2 также зарегистрированы пользователи с идентификаторами 1 и 2.

person kshaaban    schedule 19.10.2014
comment
1) Изменение условия для использования имени модели вместо псевдонима приводит к ошибке sql (насколько я понимаю, CakePHP использует псевдоним в запросе?) 2) Как это помогает мне получить доступ к модели «Студенты в уроке» - person Chaim; 19.10.2014
comment
1) Я не совсем уверен в этом, но я думаю, что вы не можете использовать псевдоним там, потому что именно здесь вы определяете псевдоним для начала! 2) Вам нужно будет добавить ту же ассоциацию (изменение имен полей ofc) в вашу модель lesson, если у вас ее там раньше не было, а затем использовать поведение Containable для обеих моделей, чтобы найти ваши данные. Проверьте этот вопрос по аналогичному вопросу. - person kshaaban; 19.10.2014