Yii2: Не работает indexBy для связанных моделей

Created on 28 Apr 2016  ·  3Comments  ·  Source: yiisoft/yii2

What steps will reproduce the problem?

Имею простые 2 таблицы, страна и город

Пытаюсь искать

FilterCity::find()
->leftJoin('filter_country', 'filter_city.filter_country_id = filter_country.id')
->select('filter_country.name')
->where(['filter_city.id' => $this->index_city])
->orderBy('filter_country.name')
->indexBy('filter_country.id') // ОБРАЩАЕМ ВНИМАНИЕ!!!!
->column();

What is the expected result?

Хочу получить примерно следующее
[1 => 'Россия'],

В результате получаю
[0 => 'Россия']

What do you get instead?

В общем если сделать ->indexBy('id') все работает.
Запрос который я указал наверху слегка утрированный, но вот тоже самое для городов

            $result = FilterCity::find()
                    ->select('name')
                    ->where(['filter_country_id' => $this->index_country])
                    ->orderBy('name')
                    ->indexBy('filter_city.id') // НЕ РАБОТАЕТ, ХОТЯ СТРАННО!!!
                    ->column();

            $result = FilterCity::find()
                    ->select('name')
                    ->where(['filter_country_id' => $this->index_country])
                    ->orderBy('name')
                    ->indexBy('id') // ВСЕ ПУТЕМ!
                    ->column();

Считаю косяком

Это лишь 2 простых утрированнных примера, на самом деле выборка намного сложней и в результате хотел бы воспользоваться indexBy и вывести в фильтр.

Additional info

База данных:

SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT=0;
START TRANSACTION;
SET time_zone = "+00:00";

-- --------------------------------------------------------

--
-- Table structure for table `filter_city`
--

CREATE TABLE IF NOT EXISTS `filter_city` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `filter_country_id` int(11) NOT NULL COMMENT 'Страна',
  `name` varchar(40) NOT NULL COMMENT 'Название города',
  `slug` varchar(40) NOT NULL COMMENT 'ЧПУ',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`),
  UNIQUE KEY `slug` (`slug`),
  KEY `filter_city_ifbk_filter_country` (`filter_country_id`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='Фильтр города' AUTO_INCREMENT=3 ;


INSERT INTO `filter_city` (`id`, `filter_country_id`, `name`, `slug`) VALUES
(1, 1, 'Санкт-Петербург', 'sankt-peterburg'),
(2, 1, 'Москва', 'moskva');

-- --------------------------------------------------------

--
-- Table structure for table `filter_country`
--

CREATE TABLE IF NOT EXISTS `filter_country` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(40) NOT NULL COMMENT 'Название страны',
  `slug` varchar(40) NOT NULL COMMENT 'ЧПУ',
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`),
  UNIQUE KEY `slug` (`slug`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='Фильтр страны' AUTO_INCREMENT=5 ;

--
-- Dumping data for table `filter_country`
--

INSERT INTO `filter_country` (`id`, `name`, `slug`) VALUES
(1, 'Россия', 'rossia'),
(2, 'Франция', 'francia'),
(3, 'Германия', 'germania'),
(4, 'Таиланд', 'tailand');

--
-- Constraints for dumped tables
--

--
-- Constraints for table `filter_city`
--
ALTER TABLE `filter_city`
  ADD CONSTRAINT `filter_city_ifbk_filter_country` FOREIGN KEY (`filter_country_id`) REFERENCES `filter_country` (`id`) ON DELETE CASCADE;
SET FOREIGN_KEY_CHECKS=1;
COMMIT;

| Q | A |
| --- | --- |
| Yii version | 2.0.7 |
| PHP version | 5.6.16 |
| Operating system | Windows 7 |

docs

Most helpful comment

->indexBy('filter_country.id') // ОБРАЩАЕМ ВНИМАНИЕ!!!!

I did not understand everything but note that indexBy() works on the result of the selcect, after the data has been retrieved from the database. That means you can not include the table name in the specification. If your select returns an id column, you should only specify id for indexBy().

All 3 comments

->indexBy('filter_country.id') // ОБРАЩАЕМ ВНИМАНИЕ!!!!

I did not understand everything but note that indexBy() works on the result of the selcect, after the data has been retrieved from the database. That means you can not include the table name in the specification. If your select returns an id column, you should only specify id for indexBy().

@cebe thanks!

    $result = FilterCity::find()
            ->leftJoin('filter_country', 'filter_city.filter_country_id = filter_country.id')
            ->select(['filter_country.name', 'filter_country.id AS id'])
            ->where(['filter_city.id' => $this->index_city])
             ->orderBy('filter_country.name')
             ->indexBy('id')
             ->column();

@cebe did you intend to leave this issue open as a documentation request? Is so, reopen it, please

Was this page helpful?
0 / 5 - 0 ratings