[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: валидация данных средствами ORM
zlodiak
уважаемые знатоки, у меня вопрос по способу валидации данных для нескольких моделей в контексте шаблона MVC. я использую для примера CMF Kohana3.2 , но вопрос более общий, как сами понимаете.

я задавал его на тематических форумах и получал неверные ответы:
http://forum.kohanaframework.org/discussio...modelyah#Item_4
http://hashcode.ru/questions/97705/orm-%D0...%D0%B9-kohana-3

я пользуюсь способом, описанным в этой статье http://kohana3.ru/module/orm#%D0%BF%D1%80%...%BD%D0%BD%D0%BE
в результате получаю в окне браузера ошибку: ErrorException [ Fatal Error ]: Call to undefined function merge()

вот содержание экшена контроллера и коллбэка:
экшн контроллера:

public function action_add()
{
if (isset($_POST['submit']))
{
$data = Arr::extract($_POST, array('category', 'title', 'text', 'active'));

print_r($data);

$Checkcategory = new Model_Checkcategory();
if($Checkcategory->check($data['category'], $data['title'], $data['text'], $data['active']))
{
$path =
Route::get('admin')->uri(array(
'controller' => 'category',
));


$this->request->redirect($path);
}
else
{
$errors = $Checkcategory->error;
}
}


$main = View::factory('admin/v_add_page')
->
bind('data', $data)
->
bind('errors', $errors);

$this->template->main = array($main);
}


коллбэк:

<?php defined('SYSPATH') or die('No direct script access.');

class Model_Checkcategory {

public $error;

public function check($category, $title, $text, $active)
{


//$error = new ORM_Validation_Exception('', Validation::factory(array()));

$menuL = ORM::factory('menuL');
$page = ORM::factory('page');

try
{
$menuL->title = $category;
$menuL->active = $active;
$menuL->check();
}
catch(ORM_Validation_Exception $e)
{
$this->error = merge($e);
//$this->error = $e->errors('validation');
}

try
{
$page->menuL_id = $menuL->pk();
$page->title = $title;
$page->content = $text;
$page->check();
}
catch(ORM_Validation_Exception $e)
{
$this->error = merge($e);
//$this->error = $e->errors('validation');
}



//$errors = $error->errors();
if( !$this->error)
{
$menuL->save();
$page->save();
// Сохранение прошло успешно
return TRUE;
}
else
{
return FALSE;
}
}

}




если интересно, то по ссылке можно скачать весь архив проекта:
prozaik.16mb.com/val/kohana_ART3.rar

как я уже говорил, получаю сообщение об ошибке ErrorException [ Fatal Error ]: Call to undefined function merge()


пробовал заменить функцию merge() на $e->errors('validation'). в этом случае на экран пользователю выводятся только ошибки из второго блока catch. ( а если второй блок убрать, то - из первого).

то есть мне нужно объединить массивы с ошибками. или использовать принципиально другой метод валидации (не $validation = Validation::factory() + if($validation->check()){})

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



Спустя 1 час, 50 минут, 15 секунд (7.04.2012 - 23:53) Zhandos написал(а):

class Model_Checkcategory {

public $error;

Лучше сделать по умолчанию массивом.

$this->error = merge($e);

Для сливания двух или более массивов есть функция array_merge. Здесь надо еще учесть, что нельзя написать
$this->error = array_merge($this->erros, $e); 

Т.к. $e это объект, что бы получить массив где значение будет текст ошибки и слить его в общий массив нужно сделать так например:
$this->error = array_merge($this->error, array_values($e->errors(TRUE)));

Вместо TRUE можешь написать директорию в папке messages, где будут лежать файлы с текстами ошибок.
Еще надо учесть что у тебя в двух моделях имеется одинаковое поле title, соответственно, если не ввести название категории и заголовок, то в массив ошибок запишется только ошибка о отсутствии заголовка. Что бы это обойти я сбросил ключи функцией array_values.

Спустя 15 часов, 6 минут, 45 секунд (8.04.2012 - 15:00) zlodiak написал(а):
ок. спасибо. я понял твой способ. но у меня еще вопрос, если можно.

дело в том, что здесь 2 блока try. а значит благодаря использованию array_values ключи массива с ошибками не будут кофликтовать друг с другом(перезаписывать). НО если блоков try будет например 10 и при этом имена полей будут иногда попадаться одинаковые, то часть значений массива ошибок потеряется. так как более новые значения перезапишут более старые.

скажи пожалуйста как можно выйти из этой ситуации?

Спустя 1 минута, 8 секунд (8.04.2012 - 15:01) zlodiak написал(а):
и еще пожалуйста скажи. как думаешь, почему подобные темы редко поднимаются на форумах? ведь если не уметь делать такие проверки, то почти с полной уверенностью можно сказать, что обучающийся будет писать говнокод

Спустя 34 минуты, 27 секунд (8.04.2012 - 15:35) caballero написал(а):
Цитата
НО если блоков try будет например 10

то это будет уже стопроцентный говнокод а не частичный как здесь
зачем там вообще try? разве функция check не может вернуть нужный резутат что надо exception кидать?

Спустя 1 день, 6 минут, 38 секунд (9.04.2012 - 15:42) Invis1ble написал(а):
С этой валидацией в моделях приходится такие костыли лепить, что проще все валидировать в контроллере, имхо. Лично я так и делаю, и мне по барабану, если кто-то будет кричать, что это не труЪ и говнокод.

Спустя 8 дней, 21 час, 2 минуты, 52 секунды (18.04.2012 - 12:45) AmberLEX написал(а):
Я тоже долго парился и сделал примерно так же, красиво-некрасиво пофиг уже
// В контроллере типа так
public function action_save()
{
$errors = Model_Blabla::save_blabla();

if ( ! $errors)
{
// сообщение
$this->session->set('message', 'Все ок');
// Типа редирект куда нужно
redirect();
}

// сообщение
$this->session->set('error', 'Фигня');
}

// Модель
class Model_Blabla extends ORM
{
public static function save_blabla()
{
$errors = array();

$obj_1 = ORM::factory('post');
$obj_1->values(Arr::extract($_POST, array('title', 'text')));
try {
$obj_1->check();
}
catch (ORM_Validation_Exception $e) {
$errors = Arr::merge($errors, $e->errors('validation'));
}

$obj_2 = ORM::factory('user');
$obj_2->values(Arr::extract($_POST, array('name', 'surname')));
try {
$obj_2->check();
}
catch (ORM_Validation_Exception $e) {
$errors = Arr::merge($errors, $e->errors('validation'));
}

// Если есть ошибки
if ($errors) {
return $errors;
}

$obj_1->save();
$obj_2->save();
}
}
В таком простом случае работает.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.