2014-02-17 5 views
0

У меня есть таблица под названием items и таблица под названием item_pics.Включить отдельный элемент из связанной таблицы

item_id, file_name и поле rank (среди прочих).


Что я ищу для каждого item моей index страницы $items массив содержит file_name из item_pics совпадающим с item «ы item_id с наименьшим rank. Таким образом, я могу получить доступ, как (или что-то подобное) это в моем Items/index.ctp:

foreach ($items as $item): 
    $img = $item['Item']['ItemPic']['file_name']; 
    ... 

Я довольно новыми для CakePHP, это мой первый проект. Я думал, что это в пределах Item модели приведет item_pics данные потянуться (хотя я полагал, что все связанные с item_pics для каждого item бы втянуты, а не только один с наименьшим rank):

public $hasMany = array(
    'ItemPic' => array(
     'className' => 'ItemPic', 
     'foreignKey' => 'item_id', 
     'dependent' => false 
    ) 
} 

, но я могу видеть что никакие данные item_pics не загружен (в нижней части items/index):

SELECT `Item`.`id`, `Item`.`title`, `Item`.`description`, `Item`.`created`, `Item`.`modified`, `Item`.`type`, `Project`.`id`, `Project`.`item_id`, `Project`.`title`, `Project`.`description`, `Project`.`rank`, `Project`.`created`, `Project`.`modified` 
FROM `laurensabc`.`items` AS `Item` 
LEFT JOIN `laurensabc`.`projects` 
AS `Project` 
ON (`Project`.`item_id` = `Item`.`id`) 
WHERE `Item`.`type` IN (1, 2) 
LIMIT 20 

также, в то время как я хотел бы projects быть соединены в view страниц, я на самом деле не нуждаются в них в index стр.

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

CakePHP - Associations - HasMany, это заставляет меня казаться, что я мог бы заказать по рангу и предел 1. Но это не сработало ... и даже если бы это было так, я бы не хотел, чтобы это повлияло на страницы view, index страница.

Мой контроллер выглядит следующим образом:

public function index($type = null) { 
    $this->Item->recursive = 0; 
    $conditions = array(); 
    if ($type == "sale") { 
     $conditions = array(
       "Item.type" => array(self::FOR_SALE, self::FOR_SALE_OR_RENT) 
     ); 
    } else if ($type == "rent") { 
     $conditions = array(
       "Item.type" => array(self::FOR_RENT, self::FOR_SALE_OR_RENT) 
     ); 
    } else { 
     $conditions = array("Item.type !=" => self::HIDDEN); 
    } 
    $paginated = $this->Paginator->paginate($conditions); 
    debug($paginated); 
    $this->set('items', $paginated); 
    $this->set('title', ($type == null ? "Items for Sale or Rent" : "Items for " . ucwords($type))); 
} 

Я также попытался это на мой контроллер, но это, кажется, не делать ничего или:

$this->paginate = array(
     'conditions' => $conditions, 
     'joins' => array(
      array(
       'alias' => 'ItemPic', 
       'table' => 'item_pics', 
       'type' => 'left', 
       'conditions' => array('ItemPic.item_id' => 'Item.id'), 
       'order' => array('ItemPic.rank' => 'asc'), 
       'limit' => 1 
      ) 
     ) 
    ); 
    $paginated = $this->paginate($this->Item); 

ответ

1

Во-первых, установить containable поведение в AppModel (или, если вы не хотите его на каждой модели, поставить его на Item модели):

public $actsAs = array('Containable'); 

Затем на вашем запросе находят:

$items = $this->Item->find('all', array(
    'contain' => array(
     'ItemPic' => array(
      'fields' => array('file_name'), 
      'order' => 'rank', 
      'limit' => 1 
     ) 
    ) 
)); 

Тогда результат массива вы можете получить доступ к нему нравится:

foreach ($items as $item): 
    $img = $item['ItemPic']['file_name']; 

Edit: Затем вы должны поставить его на запрос постраничной:

$this->paginate = array(
    'conditions' => $conditions, 
    'contain' => array(
     'ItemPic' => array(
      'fields' => array('file_name'), 
      'order' => 'rank', 
      'limit' => 1 
     ) 
    ) 
); 
+0

У меня нет запроса на поиск, где бы я положил это? – smerny

+0

О, не видел этого. Затем вы должны поместить его в свою '$ this-> paginate', хотя я не уверен на 100%, так как' paginate' не так точно точно, как запрос на поиск, и я не использовал его слишком сильно. Но попробуйте это в любом случае. Посмотрите на мое редактирование. – Eagle

+0

Кажется, работает, хотя он находится в '$ item ['ItemPic'] [0] ['file_name']'. Мне нужно больше взглянуть на эту «сдерживаемую» функцию ... но пока вы знаете, есть ли какие-либо негативы для ее использования? – smerny

0

В этом случае, я бы вероятно, по рангу и пределу 1, как вы сказали, и сделайте динамическую ассоциацию только для индексной страницы (см. http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#creating-and-destroying-associations-on-the-fly). Поэтому используйте $this->Item->bindModel(array('hasMany' => array('ItemPic' => $options))); (который, я считаю, должен заменить ваши текущие настройки для HasMany ItemPic, но вам, возможно, придется сначала отключить модем)

Ассоциации, созданные через bindModel, будут проходить только для следующего запроса, а затем вернутся к вашим обычным настройкам , если только вы не задали опцию продолжать использовать новую ассоциацию.

Что касается того, почему он не получает ItemPics с элементами или почему попытка заказа по рангу и ограничению 1 не работает для вас, я не могу сказать, не видя больше вашего кода.

+0

Я добавил мой код контроллера для 'index', есть что-нибудь еще вы хотели бы видеть? – smerny