Ошибка в Kohana 3 ORM? - PullRequest
       6

Ошибка в Kohana 3 ORM?

2 голосов
/ 13 декабря 2010

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

$results = ORM::factory('foo')->join("bar")->on("foo.foreign_id", "=", "bar.id");

Создает запрос, который не разрешает имена таблиц явно:

SELECT * FROM `foo` JOIN `bar` ON (`foo`.`foreign_id` = `bar`.`id`)

Что дает (в phpMyAdmin) таблицу, которая выглядит следующим образом:

id    time          foreign_id      blah_int    id  baz
4     1291851245    3           0               3   52501504

Обратите внимание, что есть два столбца id, один для таблицы foo и один для bar. Это настоящая проблема. Потому что теперь, в моих результатах, если я перейду через ...

foreach ($results as $result) {
    echo $result->id;    // prints 3!!!
}

Поскольку мои результаты должны быть foo объектами, я ожидаю получить идентификатор 4, но он дает мне 3 из-за соединения. Это ошибка в библиотеке ORM? Должен ли я использовать другой метод, чтобы ограничить свои результаты из запроса? Я действительно не хочу делать два отдельных запроса, когда я загружаю все идентификаторы bar, а затем загружаю свои foo таким образом, но похоже, что мне нужно.

1 Ответ

1 голос
/ 01 июня 2011

Вы должны использовать объект базы данных для создания необработанных запросов, а не ORM, как это:

$results = DB::select()->from('foo')->join('bar')->on("foo.foreign_id", "=", "bar.id")->execute();

Однако вам нужно будет указать некоторые псевдонимы столбцов, чтобы ваш запрос работал, если вы не используете ORM, как предполагалось.

Использование ORM

Если вы хотите использовать ORM, вам нужно определить отношения в вашей модели. Вы упомянули, что они имеют отношения с другой таблицей, поэтому в вашем случае вы можете использовать отношение «многие-через», как это:

protected $_has_many = array(
    'bars' => array('model' => 'bar', 'through' => 'other_table', 'foreign_key' => 'foreign_id'),
    );

Хотя ваш приведенный пример показывает, что прямое отношение has_many будет работать:

protected $_has_many = array(
    'bars' => array('model' => 'bar','foreign_key' => 'foreign_id'),
    );

Это позволит вам получить доступ ко всем барам, используя оператор типа

$bars = $results->bars->find_all();
foreach($bars as $bar)
{
    echo $bar->id; // should echo 4, assuming one record in bars with id 4
}

Справочное руководство Kohana 3.1 ORM - хорошее место для начала, если вы хотите узнать больше об ORM и отношениях

Использование объекта базы данных Kohana и построителя запросов

Если вы предпочитаете специальные запросы и выполняете объединения с использованием построителя запросов, у вас, скорее всего, будут конфликтующие имена столбцов, независимо от того, используете ли вы Kohana или просто необработанные запросы (pop "SELECT * FROM foo JOIN bar ON (foo. foreign_id = bar. id) "в MySQL, и вы получите точно такой же результат).

Kohana, точно так же, как MySQL позволяет вам определять псевдонимы столбцов именно по этой причине. (См. здесь для получения дополнительной информации )

Перепишите ваш запрос следующим образом:

$results = DB::select('id', 'time', 'foreign_id', array('bar.id', 'bar_id'), 'baz')->from('foo')->join("bar")->on("foo.foreign_id", "=", "bar.id")->execute();

Это вернет:

id    time          foreign_id      blah_int    bar_id   baz
4     1291851245    3               0           3        52501504
...