Пользовательский объект, возвращаемый объединением в активной записи Codeigniter - PullRequest
1 голос
/ 05 июля 2011

У меня есть две таблицы базы данных:

Места
идентификатор
имя

Пользователи
идентификатор
LOCATION_ID
last_name
first_name

У меня также есть Пользователь и Класс местоположения , они оба расширяют Модель и содержат некоторые пользовательские методы. Например, в классе Пользователь существует метод get_full_name () .

Я использую следующие коды для загрузки данных,

$this->db->select('users.id, locations.name as location_name, users.last_name, users.first_name');
$this->db->from('users');
$this->db->join('locations', 'users.location_id = location.id');
$query = $this->db->get();
$users= $query->custom_result_object('User'); //now $users is an array of User object

custom_result_object - это встроенная, но недокументированная функция в Codeigniter. Он принимает строку с именем класса и будет использовать ее для создания объектов этого класса.

С помощью вышеуказанных кодов я могу получить доступ к таким данным,

foreach($users as $user)
{
 echo $user->id;
 echo $user->get_full_name();
 echo $user->location_name;
}

Но, как вы можете видеть, location_name теперь является полем объекта Пользователь , я хочу, чтобы объект Пользователь имел поле Местоположение объект что позволяет мне использовать это так,

foreach($users as $user)
{
 echo $user->id;
 echo $user->get_full_name();
 echo $user->location->name; // Location is an object
}

Я не хочу использовать DataMapper ORM или любые другие ORM, а также хотел бы избежать проблемы производительности запросов N + 1.

Как я могу сделать это с минимальным количеством кодов?

Примечание: я создал этот пример только для демонстрации, в моем реальном случае довольно много таблиц и классов (для которых определены пользовательские методы).

Большое спасибо всем вам.

Ответы [ 3 ]

2 голосов
/ 29 мая 2012

Рассматривали ли вы следующее?

class User {

    var location;

    public function location()
    {
        if ( empty($this->location) )
        {
            $ci =& get_instance(); 
            $this->location = $ci->db->get_where('locations', array('id' => $this->location_id))->row();
        }

        return $this->location;

    }

}

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

0 голосов
/ 31 марта 2016

получить идентификатор местоположения от пользователя таблицы, использовать его номер, чтобы получить из местоположений таблицы идентификатор объекта.и вставь.

0 голосов
/ 13 октября 2011

Я задавал то же самое для себя, но обнаружил, что самый простой способ - это перебрать каждый результат (в вашем случае, пользователя) и выбрать соответствующий дочерний элемент (местоположение) и установить его в поле в родительском объекте (user-> location).

Единственный альтернативный способ, который я могу придумать, заключается в том, чтобы отредактировать (или расширить и создать свой собственный набор БД) класс db_result, чтобы использовать getters / setters вместо прямых полей - возможно, с помощью call_user_func_array ().В этот момент вы можете кодировать функцию setId () в пользовательской модели, чтобы установить поле $ location после получения userId / внешнего ключа.

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