Как сделать модели "hasMany" и "ownTo"? (То же самое, что и cakePHP) - PullRequest
0 голосов
/ 01 октября 2011

В настоящее время я работаю над моей инфраструктурой MVC (на PHP).Я видел, что cakePHP имеет возможность использовать функции "ownTo" и "hasMany".Я пытаюсь создать свою собственную функцию и столкнулся с проблемой.

Допустим, у нас есть таблица встреч (id, где, date, year_id) и таблица годов (id, year).Я знаю, что этот пример можно сделать с одной таблицей без проблем, но это всего лишь пример.

class appointment_model extends model{
    public $_belongs_to= array('table'=>'year','field_connector'=>'year_id');
    public $one_value;
}

......

class year_model extends model{
    public $_has_many= array('table'=>'appointment','field_connector'=>'year_id');
    public $many_values;
}

....

class model{

private function select($query=null){
    if(!$query)die("Query cannot be null. Line num: " . __LINE__);
    $results = $this->_db->mysql_select($query);
    if(count($results)==1){
        $one = $this->initialize($results[0]);
        $this->_do_for_other_tables($one);
        return $one;
    }elseif(count($results)>1){
        $returns = array();
        foreach($results as $result){
            $one = $this->initialize($result);
            $returns[] = $this->_do_for_other_tables($one);     
        }
        return $returns;
    }else{
        return null;
    }

}


private function _do_for_other_tables(&$one, $rec=1){


    if(property_exists($this, 'many_values')){
        if(!empty($one->many_values))return;
        $many = functions::load_model($this->_has_many["table"]);
        $res = $many->find_by($this->_has_many["field_connector"], $one->id);
        $one->many_values = $res;
    }
    elseif(property_exists($this, 'one_value')){
        if(!empty($one->_belongs_to))return;
        $only_one = functions::load_model($this->_belongs_to["table"]);
        $field = $this->_belongs_to['field_connector'];
        $res = $only_one->find_by('id', $one->$field);
        $one->one_value = $res;
    }

}

}

В основном здесь происходит то, что я вхожу в бесконечный цикл.Любое предложение, как я могу это исправить?Если мне нужно объяснить это подробнее, просто скажите это.

Спасибо :)).

1 Ответ

1 голос
/ 01 октября 2011

Ваша проблема заключается в том, что вы относитесь к свойствам hasMany, ownTo, hasOne, и т. Д. Как к простым свойствам, а не рассматриваете их как двусторонние отношения. То, что я сделал во многих моих собственных платформах, - это инициализация этих свойств вручную программистом, но когда класс инициализируется, вы проверяете эти свойства и генерируете один объект, который связывает их вместе.

Создайте класс, подобный объекту System_DB_Relationship, и вы поместите одну и ту же копию в две инициализированные модели. Если вы не представляете свои модели как шаблон проектирования Factory, вы также можете использовать статическую модель $ Relationship для хранения ваших отношений. Я склонен идти на заводскую / активную запись, поэтому лучше ими управлять. Теперь, в зависимости от логики базового класса вашей модели, вы можете захотеть поместить флаг в отношение, чтобы сказать «эй, это отношение было использовано», поэтому вы больше не переходите в него.

Другой способ - всегда работать по убыванию. То есть игнорируйте hasMany, когда он найден, и создайте только прокси-метод для загрузки дочерних элементов, но загрузите все ownTo, чтобы родительский элемент загружался по умолчанию. Заметьте, однако, что эти методы могут стать опасными, если у вас большой набор классов, поэтому то, что я реализую в своих фреймворках, это обычно загрузка параметров, которые говорят, загружают X уровней отношений. И когда вы хотите использовать hasMany, вы просто используете __call (), чтобы перехватить вызов «$ myobject-> subobjects ()» и просто загрузить их на лету.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...