Присоединение к родительской таблице в CakePHP Model-> find () - PullRequest
0 голосов
/ 09 ноября 2011

У меня есть иерархия моделей CakePHP, которая выглядит следующим образом:

Users > Feedfolders > Feeds > Entries

Изнутри FeedsController я пытаюсь получить количество всех непрочитанных записей на основе идентификатора пользователясгруппированы по идентификатору канала.Я действительно в растерянности относительно того, как я должен делать это таким образом, чтобы это соответствовало способу действий Кейка.Мне кажется, что понимание Cake моделей, основанных на свойствах $belongsTo и $hasMany в моделях, должно позволить ему надлежащим образом разрешить объединения, но я не уверен, что делаю неправильно.Я попробовал несколько find() вариантов без успеха.Совсем недавно я пытался:

$result = $this->Feed->find('all', array(
  'conditions' => array('User.id' => $this->Auth->user('id'), 'Entry.read' => 1),
  'fields' => array('count(Entry.feed_id) as Count', 'Entry.feed_id'),
  'group' => 'Entry.feed_id',
  'recursive' => 2)
);

, который генерирует следующий SQL:

SELECT count(`Entry`.`feed_id`) as Count, `Entry`.`feed_id`, `Feed`.`id`
FROM `feeds` AS `Feed`
LEFT JOIN `feedfolders` AS `Feedfolder` ON (`Feed`.`feedfolder_id` = `Feedfolder`.`id`)  
WHERE `User`.`id` = 5
AND `Entry`.`read` = 1
GROUP BY `Entry`.`feed_id`   

, что приводит к следующей ошибке:

SQL Error: 1054: Unknown column 'Entry.feed_id' in 'field list' [CORE/cake/libs/model/datasources/dbo_source.php, line 684]

Я вижу проблему сSQL, и может вручную написать запрос, чтобы сделать то, что я хочу, но это похоже на то, что должно быть выполнимо в CakePHP, не прибегая к ручной SQL.

Как мне настроить find() звоните, чтобы делать то, что я хочу, и имеет ли смысл мой план по поиску непрочитанных записей через FeedsController с точки зрения MVC?

Ответы [ 3 ]

1 голос
/ 09 ноября 2011

Вы можете использовать это из контроллера Feeds .

/**
 * Bind the Feed model to the Entry model
 * and set a condition of 'read' => false
 */
$this->Feed->bindModel(array(
  'hasMany' => array(
    'Entry' => array(
      'conditions' => array(
        'Entry.read' => false
      )
    )
  )
));

/**
 * Get all the feeds and their accompanying
 * entries that belong to the current user
 */
$unread = $this->Feed->find('all', array(
  'conditions' => array(
    'Feedfolder.user_id' => $this->Auth->user('id')
  )
));

Что здесь происходит?

Во-первых, мы связываем модель Feed , используя hasMany с моделью Entry . В то же время мы также установили условие ('Entry.read' => false) , обеспечивающее возврат только непрочитанных сообщений.

Во-вторых, мы можем вызвать поиск для модели Feed , установив условие, что Feedfolder должен принадлежать текущему пользователю.

0 голосов
/ 09 марта 2015

попробуйте

$this->Category->bindModel(
            array('belongsTo' => array(
                    'ParentCategory' => array('className' => 'Category',

 'foreignKey' => 'parent_id'),
    )));
0 голосов
/ 10 ноября 2011

Давайте попробуем еще раз.На этот раз я работаю напрямую с контроллера Entries .

/**
 * Unbind the existing relationship with Feed
 */
$this->Entry->unbindModel(array(
  'belongsTo' => array('Feed')
));

/**
 * Explicitly bind of the 'parent' models
 */
$this->Entry->bindModel(array(
  'hasOne' => array(
    'Feed' => array(
      'foreignKey' => false,
      'conditions' => array('Feed.id = Entry.feed_id')
    ),
    'Feedfolder' => array(
      'foreignKey' => false,
      'conditions' => array('Feedfolder.id = Feed.feedfolder_id')
    ),
    'User' => array(
      'foreignKey' => false,
      'conditions' => array('User.id = Feedfolder.user_id')
    )
  )
));

/**
 * Find the entries that are unread and belong to the current user
 * and then Group by Feed.id
 */
$unread = $this->Entry->find('all', array(
  'fields' => array(
    'Feed.Title',
    'COUNT(Entry.id) AS UnreadCount'
  ),
  'conditions' => array(
    'Entry.read' => 0,
    'User.id' => $this->Auth->user('id')
  ),
  'group' => array(
    'Feed.id'
  )
));

Что здесь происходит?

Во-первых, мы отсоединяем Feed model.

Во-вторых, мы явно связываем модель Entry с Feed , Feedfolder и User .Это препятствует тому, чтобы Cake пытался использовать его автоматическое совершенство (что, впрочем, еще здорово).

Наконец, мы вызываем находку для модели Entry и устанавливаем наши необходимые условия: entryнепрочитанные и принадлежат текущему пользователю .Затем мы группируем все это по Feed.id .

...