Контент


[Ko3.3] Изменения в модуле ORM

  • Добавлены методы has_any($alias, $far_keys = NULL) и count_relationships($alias, $far_keys = NULL). Первый метод определяет, имеет ли модель хотя бы одну запись в указанной связи $alias. А метод count_relationships() возвращает общее количество записей по данной связи. Например, если в системе имеются роли ‘login‘ (ID=1) и ‘admin‘ (ID=2), и пользователь $user имеет только роль ‘login‘, то:

    $user->has('roles', array(1, 2)); // FALSE
    $user->has_any('roles', array(1, 2)); // TRUE
    $user->count_relationships('roles', array(1, 2)); // 1

    (#4349)

  • Добавлен защищенный метод _build_select(). Он позволяет указать имена полей, которые будут загружены в модель. По умолчанию загружаются все поля, перечисленные в свойстве $_table_columns (если оно не заполнено вручную, то берутся все поля таблицы). #3587
  • Добавлен метод using() для использования SQL-условия USING. В Query Builder он есть, а вот в ORM его добавить забыли. #4049
  • Теперь валидация при сохранении/обновлении модели может происходить даже если модель не была изменена. Для этого достаточно отсутствия факта валидности модели на данный момент (например, модель загрузили, но не проверяли вручную через check()), либо был передан объект Validation (т.н. «extra validation» или «внешняя валидация«). #4423, #4424
  • Исправлено неправильное имя файла для ошибок внешней валидации. #4185
  • Исправлена десериализация данных, являющихся массивом. Т.е. в 3.2, если в каком-либо поле модели хранится массив, то после десериализации модели в нем будет уже не массив, а объект stdClass. #4188

Auth ORM

  • При нестандартном имени ключа в модели User попытка создания пользовательского токена (т.е. логин с $remember==TRUE) приводила к ошибке. #4222
Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в Kohana3.

Теги: , , , .


Комментарии (11)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. SVat пишет:

    Добавлен метод using() для использования SQL-условия USING. В Query Builder он есть, а вот в ORM его добавить забыли.

    Вот я для себя переписывал ORM: https://github.com/svat/ORM/blob/master/classes/kohana/orm.php там сам класс Kohana_ORM наследуется от Database_Query_Builder_Select. Соответственно при добавлении новых методов в Database_Query_Builder_Select они автоматически стают доступными и в ORM. Почему то разработчики Kohana не хотят сделать так же, а просто дублируют в ORM методы из QB, тем самым только всё усложняя.

  2. biakaveron пишет:

    Не уверен насчет усложнения, т.к. количество подобных методов в принципе ограничено. Раньше вообще использовался __call(), а ORM содержал список методов QBuilder’а, которые можно было заюзать. Вероятно, сейчас просто решили избавиться от одного медленного магического метода, создав много быстрых.

    Да и самого дублирования тут нет, т.к. в ORMе вызовы просто складываются в очередь, а затем обрабатываются все тем же QBuilder’ом.

  3. Денис пишет:

    Добрый день! Бьюсь над проблемкой уже 3 дня. Назрел вопрос в ОРМе коханы есть возможность создать цепочку из моеделей? Тоесть у меня есть таблица Cities (id, name) таблица Users(id, city_id, name) и таблица Products(id, user_id, name). Создал 3 модели сооветсвенно в City прописал has_many User. В User belongs_to City и has_many Products. В Product belongs_to User. Теперь пытаюсь Зная ID из таблицы Cities вытянуть все данные из табоицы Products по такой цепочке city->users->products. Но вот такой запрос

    $products = ORM::('city', 1)->users->products->find_all();

    не чего не возвращает а если копать глубже то в SQL запрос генерится вот с таким условием WHERE user_id IS NULL Собственно такой вопрос вообще ли реально реализовать такую цепочку? city.id->user.city_id->products.user_id и сортировать это все по определенному полю?

  4. biakaveron пишет:

    А как Вы себе представляете себе работу такой цепочки? $city->users->find_all() должен вернуть не одну модель ORM, а Database_Result. А $city->users->products не будет работать, так как $city->users представляет собой незагруженную модель User, в которой установлено условие where('city_id', '=', 1). Естественно, обращение к связи в незагруженной модели ни к чему не приведет.

    Варианты:

    1. В лоб. Извлекаем всех пользователей ($city->users->find_all()). Затем для каждого из них загружаем продукты. Много запросов, явный overhead.
    2. Используем QBuilder.

    $users = $city->users->find_all()->as_array(NULL, 'id'); 
    $products = ORM::factory('product')->where('user_id', 'IN', $users)->find_all();


    3. Если так уж важно уметь выбрать продукт по городу, почему бы не связать продукт с городом напрямую? При создании продукта просто сохраняйте в нем city_id, взятый из модели пользователя. И в дальнейшем просто обращаться $city->products.

  5. Денис пишет:

    Ну собственно я так и думал а плясать с бубном начал после ответа на хэшкоде! с city_id в products значит изначально было не плохим моим решением. Да и пользователи гораздо реже меняют свой город. Спасибо за ответ!

  6. biakaveron пишет:

    Денормализация БД — это вполне естественный шаг, способный весьма существенно уменьшить количество запросов. А при смене города пользователем надо инициировать смену города в связанных сущностях (в данном случае в продуктах). Это несложно, причем можно повесить на события (Events), если они используются на сайте.

  7. Святослав пишет:

    ребята помогите новичку
    ORM_Validation_Exception [ 0 ]: Failed to validate array

    MODPATH\orm\classes\Kohana\ORM.php [ 1272 ]

    если закоментить строчку то пустит но потом валидацыя вопше не работает кохана 3.3 что делать ??

    код матода

    public function action_index()
    {
    $auth = Auth::instance();
    $date=array();
    if($auth->logged_in())
    {
    Controller::redirect('');
    }
    else {
    if(isset($_POST['btnsubmit']))
    {
    $login=Arr::get($_POST,'login','');
    //$login=$auth->login($this->request->post('login'),
    //$this->request->post('password'));
    $password=Arr::get($_POST,'password','');
    if($auth->login($login,$password))
    if($login)
    {
    $session=Session::instance();
    $auth_redirect=$session->get('auth_redirect','');

    HTTP::redirect($auth_redirect);
    $session->delete('auth_redirect');
    }
    else {
    $date["error"]= "";
    }
    }
    }

    $this->template->content=View::factory('authview',$date);
    }

  8. biakaveron пишет:

    А что мешает посмотреть, что это за ошибки валидации?

  9. Святослав пишет:

    прикол в том, что я не делал валидацыю ето системная ошибка. Как мне ето обойти??

    $array = $this->_validation;
    1269
    1270 if (($this->_valid = $array->check()) === FALSE OR $extra_errors)
    1271 {
    1272 $exception = new RM_Validation_Exception($this->errors_filename(), $array);
    1273
    1274 if ($extra_errors)
    1275 {
    1276 // Merge any possible errors from the external object
    1277 $exception->add_object(‘_external’, $extra_validation);

  10. biakaveron пишет:

    Что за системная ошибка? Валидация происходит автоматически при сохранении (обновлении) модели. Заверните свой код в try {} catch (ORM_Validation_Exception $e) {} и посмотрите на $e->errors(‘validation’);

    Еще лучше (в том числе и для понимания внутренностей фреймворка) — включить отладчик типа XDebug и пройтись пошагово по данному участку кода. Но, подозреваю, Вы предпочитаете более легкие пути…

    PS. И почитайте уже про валидацию в целом, и валидацию ORM в частности

  11. Святослав пишет:

    буду пробовать и учиться



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.