KOHANA ORM

aleksei5698

Новичок
Кто работает с кохановским ОРМ, прошу помощи.
Для примера, дана таблица студентов и таблица телефонов, у каждого студента много телефонов. Хочу вытащить всех студентов со всеми телефонами.
Пишу:

PHP:
 $students = ORM::factory('students')->find_all();                      
        foreach ($students as $student){            
            $phones = $supply->phones->find_all();
            foreach ($phones as $phone) {
                echo $phone->phone . '</br>';
            }         
        }
В результате массив $phones пуст. :((

Дело оказалось в следующем:
PHP:
$students = ORM::factory('students')->find_all();                      
foreach ($students as $student){
  echo Debug::vars($student->pk());
}
PK везде NULL !!!

Хотя если сделать
PHP:
$student = ORM::factory('students', <какой то id>)}
echo Debug::vars($student->pk());
// возвращает <какой то id>

Вопрос это баг?

Пока решил проблему профиксив ORM.php

PHP:
public function pk()	{
            // START FIX BUG
            if (is_null($this->_primary_key_value))
                    if (isset($this->_object[$this->_primary_key]))
                        $this->_primary_key_value =  $this->_object[$this->_primary_key];   
            // END FIX BUG
		return $this->_primary_key_value;
	}
Чем черевато? Кто сталкивался?
 

Adelf

Administrator
Команда форума
PHP:
 $students = ORM::factory('students')->find_all();                      
        foreach ($students as $student){            
            $phones = $supply->phones->find_all();
            foreach ($phones as $phone) {
                echo $phone->phone . '</br>';
            }         
        }
Погляди ОЧЕНЬ ВНИМАТЕЛЬНО на этот код. И увидишь очевидную ошибку.
 

aleksei5698

Новичок
PHP:
 $students = ORM::factory('students')->find_all();                      
        foreach ($students as $student){            
            $phones = $student->phones->find_all();
            foreach ($phones as $phone) {
                echo $phone->phone . '</br>';
            }         
        }
Блин, неправильно запостил пример $supply ->> $student
Однако, суть не в этом.
Попробуйте кто нибудь у себя, если не в лом. Kohana 3.2
 

aleksei5698

Новичок
код Model_* классов нужен...
Таблица студентов
PHP:
CREATE TABLE STUDENT (
    ID    INTEGER NOT NULL,
    NAME  VARCHAR(10) NOT NULL
);

ALTER TABLE STUDENT ADD CONSTRAINT PK_STUDENT PRIMARY KEY (ID);
Телефоны студентов
PHP:
CREATE TABLE STUDENT_PHONE (
    ID          INTEGER NOT NULL,
    STUDENT_ID  INTEGER NOT NULL,
    PHONE       VARCHAR(11) NOT NULL
);

ALTER TABLE STUDENT_PHONE ADD CONSTRAINT PK_STUDENT_PHONE PRIMARY KEY (ID);
ALTER TABLE STUDENT_PHONE ADD CONSTRAINT FK_STUDENT_PHONE_1 FOREIGN KEY (STUDENT_ID) REFERENCES STUDENT (ID) ON DELETE CASCADE;
модель студентов
PHP:
class Model_Student extends ORM {
    protected $_table_name = 'student';
    protected $_has_many = array(
        'phones' => array(
            'model' => 'student_phone',
        )
    );

}
модель телефонов студентов
PHP:
class Model_Student_Phone extends ORM {
     protected $_table_name = 'student_phone';
}
контроллер
PHP:
class Controller_Welcome extends Controller_Template {

    public function action_index() {
        $students = ORM::factory('student')
                ->find_all();
        foreach ($students as $student) {
            echo 'ID: ' . $student->id . '</br>';
            echo 'Name: ' . $student->name . '</br>';
            foreach ($student->phones->find_all() as $phone)
                echo 'Phone: ' . $phone->phone . '</br>';;
        }
    }
}
игого имеем count($student->phones->find_all()) === 0
 

A1x

Новичок
я бы все таки указал в обоих моделях _primary_key а не надеялся на то что ID и id одно и то же
еще в _has_many для phones указал бы 'foreign_key' => 'STUDENT_ID'

еще можно вывести echo View::factory('profiler/stats'); чтобы посмотреть какие запросы выполняются
 

aleksei5698

Новичок
Проблема решена.
К слову, кроме этой проблемы наблюдался еще и ряд других, к примеру простая конструкция бросает Exception:
PHP:
 foreach (ORM::factory('supply')->with('dwelling')->find_all() as $supply){
         echo $supply->dwelling->name;         
        }
В проекте применяется база Firebird, был проведен тест с mysql - подобных проблем не возникло.

Причина в этом
ссылка на баг bug

Класс ORM намерено использует этот баг при создании модели в mysql (!)
В firebird (и возможно в других базах) этот трюк не проходит из за отсутствия
возможности передать в метод ibase_fetch_object имя создаваемого класса.
(Даже если бы такая возможность была, не факт что баг повторился бы)

Предлагаемое автором решение по ссылке выше я считаю неверным
Сделал себе следующий костыль
PHP:
class ORM extends Kohana_ORM {   
    /**
     * Этот метод необходим драйверу Firebird из за бага ORM.
     * @param array $cast_data 
     */
    public function hack_load_values(array $cast_data){
        $this->_load_values($cast_data);
    }
}
Сам драйвер вызывает этот метод если переденный класс является наследником ORM
 

confguru

ExAdmin
Команда форума
Уволил бы за такой код. Где проверка что результат массив?
ORM::factory('supply')->with('dwelling')->find_all()

Проблема решена.
К слову, кроме этой проблемы наблюдался еще и ряд других, к примеру простая конструкция бросает Exception:
PHP:
 foreach (ORM::factory('supply')->with('dwelling')->find_all() as $supply){
         echo $supply->dwelling->name;         
        }
 

aleksei5698

Новичок
Уволил бы за такой код. Где проверка что результат массив?
ORM::factory('supply')->with('dwelling')->find_all()
???

PHP:
/**
	 * Finds multiple database rows and returns an iterator of the rows found.
	 *
	 * @return Database_Result
	 */
	public function find_all()
	{
		<...>
	}
 
Сверху