TIP: Use Markdown or, <pre> for multi line code blocks / <code> for inline code.
These forums are read-only and for archival purposes only!
Please join our new forums at discourse.kohanaframework.org
Кто то вже реализовывал ORM $column_aliases, $teble_views?
  • На данный момент существует возможность указать название таблицы, первичный ключ для конкретной БД, а также можно создавать алиасы для ORM моделей.

    Но как на счет алиасов для полей в ORM модели? Также интересно реализовал ли кто-то уже вариант указания для ORM модели не физическую таблицу в БД, а селект (по-сути вьюху БД)?

  • алиасы полей уже есть:

    protected $_table_columns = array(
        'id' => array(
            'type' => 'int',
            // ...
            'column_name' => 'id',
            // ...
            'key' => 'PRI',
            'privileges' => 'select,insert,update,references',
        ),
    
  • @WinterSilence, спасибо. Но похоже, что в таком случаи, нужно перечислять абсолютно все нужные поля. Неплохо было бы мерджить существующие поля, как это реализовано с конфиг файлами.

    UPD: Стоп, не похоже, чтобы вообще можно было бы таким способом делать алиасы:

    // Пишу сначала так
    'username' => array(
                'column_name' => 'username',
            ),
    /**
     * В результате формируется запрос
     * select username as username from users where ID = 1
     */
    
    // Потом пишу так
    'username' => array(
                'column_name' => 'username1',
            ),
    /**
     * В результате формируется запрос
     * select username as username from users where ID = 1
     * тоесть вообще ничего не меняется
     */
    
    // Потом пишу так
    'username1' => array(
                'column_name' => 'username',
            ),
    /**
     * В результате формируется запрос
     * select username1 as username1 from users where ID = 1
     */
    
  • облажался :( , но думаю пилить надо в этом направлении + можно еще облегчить себе работу по валидации данных и автоматически задавать часть проверок на основании типа поля.

  • $_primary_key = 'kk_id';

    Решает эту проблему, надо проверить точно, но вроде когда-то где-то использовал.

    Если надо иметь модель ORM с разными ключами, то я описывал один базовый класс KKK и создавал новые, которые наследовали KKK.

  • @Ramallah, про возможность переименовать $_primary_key, я ж написал, что это предусмотрено. Я спрашивал о алиасах всех полей с БД с помощью ORM. Нашел решение достаточно простое, хотя немного "на костылях". В классе ORM сначала создаете массив алиасов вида

    protected $column_aliases = array(
            'id_from_db' => 'id_in_code',
        );
    

    потом переписываете метод _build_select() так

       protected function _build_select()
        {
            if ($this->column_aliases)
            {
                $columns = array();
                foreach ($this->_table_columns as $column => $_)
                {
                    $alias = Arr::get($this->column_aliases, $column, $column); // Ці псевдоніми можна прописати у відповідних ORM моделях, наприклад ['id'=>'uid']
                    
                    $columns[] = array($this->_object_name.'.'.$column, $alias);
                }
    
                return $columns;
            }
            else
            {
                return array($this->_object_name.'.*');
            }
        }

    Ну и на последок переписываете метод _load_values()

        protected function _load_values(array $values)
        {
            $alias_or_primary_key = Arr::get($this->column_aliases, $this->_primary_key, $this->_primary_key);
            
            if (array_key_exists($alias_or_primary_key, $values))
            {
                if ($values[$alias_or_primary_key] !== NULL)
                {
                    // Flag as loaded and valid
                    $this->_loaded = $this->_valid = TRUE;
    
                    // Store primary key
                    $this->_primary_key_value = $values[$alias_or_primary_key];
                }
                else
                {
                    // Not loaded or valid
                    $this->_loaded = $this->_valid = FALSE;
                }
            }
    
            // Related objects
            $related = array();
    
            foreach ($values as $column => $value)
            {
                if (strpos($column, ':') === FALSE)
                {
                    // Load the value to this model
                    $this->_object[$column] = $value;
                }
                else
                {
                    // Column belongs to a related model
                    list ($prefix, $column) = explode(':', $column, 2);
    
                    $related[$prefix][$column] = $value;
                }
            }
    
            if ( ! empty($related))
            {
                foreach ($related as $object => $values)
                {
                    // Load the related objects with the values in the result
                    $this->_related($object)->_load_values($values);
                }
            }
    
            if ($this->_loaded)
            {
                // Store the object in its original state
                $this->_original_values = $this->_object;
            }
    
            return $this;
        }
    

    Все, теперь можно писать код для модулей ORM и не парится, если поля в БД меняются, ну или вообще применяете ранее написанный код под другие поля.

  • "теперь можно писать код для модулей ORM и не парится, если поля в БД меняются" так для этого наследование Kohana_Model -> Model сделано. Алиасы нужны когда поля имеют слишком длинные названия, других смыслов их вводить не вижу.

  • @WinterSilence, весь код класса Kohana_Model состоит с одного метода

    public static function factory($name)
        {
            // Add the model prefix
            $class = 'Model_'.$name;
    
            return new $class;
        }
    

    Не вижу взаимосвязи с возможностью создавать алиасы полей.

    П.С. по поводу "зачем нужны алиасы", то а как быть если сначала код был написан под поле id, но которое потом переименовалось в БД на uid. Делать риплейс по всему проекту?

  • А вообще нафига примарикей менять, на то он и есть, что бы отбить конкретную запись. Что бы строить алиасы с отличным от дефолтного ключом у меня как обычно был отличная приблуда и где-то лежит в закормах )

  • @like_you я не про конкретны класс, а про систему наследования коханы в целом.

    " если сначала код был написан под поле id, но которое потом переименовалось в БД на uid."
    да, это конечно тоже - действительно нужная фишка. но это при условии что в модели есть дополнительные методы в которых фигурируют названия измененных полей, если нет, то достаточно переопределить $_table_columns. со связями ситуация обстоит аналогично.
    можно не создавать лишнее свойство, а использовать $_table_columns[...]['column_name'] раз уж оно реализовано

  • @Ramallah, ты как то очень бегло вникаешь в суть темы - сделать алиасы для всех полей БД, и сделать возможность обращятся не только к физ. таблице, но и к селекту точно так же как к таблице (по-сути - как к вьюхе в БД)

  • @like_you, ну понимаю настолько, насколько проясняется по топику. Просто я всегда пытаюсь найти проблему не во фрейморке, а к подходу к решению задачи. Просто часто сталкивался, что кольца меняли через выхлопную трубу.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion