Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > DBIx::Class, триггеры или что-то вроде того


Автор: Logo 13.5.2010, 15:46
Есть DBIx::Class(Catalyst) и MySQL. Можно ли к полям привязать некоторую функцию-чекер, что бы перед добавлением записи в базу данных проверить это поле, и в случае неудачи вернуть ошибки, для последующей передачи в браузер пользователя?

Автор: odmink0 14.5.2010, 01:07
Переопредели метод new() твоего ResultSet-а (строки таблицы) так, чтобы он вываливал исключение при попытке создать строку с невалидным полем - и отлавливай это исключение при вызове $rs->create( \%fields_hash ); в контроллере Catalyst.

Не забудь в конце своего переопределенного new() вызвать $class->next::method($fields_hash_ref);

Автор: Logo 14.5.2010, 09:54
Но класс DBIx::Class::ResultSet один для всех таблиц, а мне нужно сделать проверку для конкретной таблицы.

Автор: odmink0 14.5.2010, 11:18
Resultset - это объект, который представляет твою таблицу или результат выполнения запроса. Файлы, представляющие классы этого объекта, находятся в каталоге lib/MyApp/Schema/MyDB/Result.

Вот здесь можно получить некоторую информацию:
http://www.slideshare.net/kostenko/dbixclass
http://www.slideshare.net/jshirley/demystifying-dbixclass

Ну и в мануале, конечно ;)

Автор: Logo 14.5.2010, 11:32
Насколько я понимаю, то что лежит lib/MyApp/Schema/, это классы схемы.
ref $c->model('MyAppDB::Table') выдает DBIx::Class::ResultSet.

Автор: odmink0 14.5.2010, 13:52
Цитата(Logo @ 14.5.2010,  11:32)
Насколько я понимаю, то что лежит lib/MyApp/Schema/, это классы схемы.
ref $c->model('MyAppDB::Table') выдает DBIx::Class::ResultSet.


Да, я слегка напутал в первом посте.

В каталоге lib/MyApp/Schema/MyDB/Result находятся классы, описывающие строки таблицы.
При вызове метода $resultset->create( \%fields ); (создание новой строки таблицы) вызывается метод new() класса, который описывает эту строку - одного из тех, которые находятся в каталоге Result. Вот именно там-то тебе и надо делать проверку - т.е. переопределять этот метод.

Код примерно такой:
Код

package TestApp::Schema::MyDB::Result::User;

# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE

use strict;
use warnings;

use base 'DBIx::Class::Core';

__PACKAGE__->load_components("InflateColumn::DateTime");
__PACKAGE__->table("users");

__PACKAGE__->add_columns(
  "user_id",
  { data_type => "integer", is_nullable => 0 },
  "email",
  { data_type => "varchar", is_nullable => 0, size => 255 },
  "password",
  { data_type => "varchar", is_nullable => 0, size => 255 },
  "first_name",
  { data_type => "varchar", is_nullable => 0, size => 255 },
  "last_name",
  { data_type => "varchar", is_nullable => 0, size => 255 },
  "phone",
  { data_type => "varchar", is_nullable => 0, size => 255 },
);
__PACKAGE__->set_primary_key("uid");


# Created by DBIx::Class::Schema::Loader v0.06001 @ 2010-05-14 11:25:12
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:B6bdyl12Ciynhg0PqORdnA

# You can replace this text with custom content, and it will be preserved on regeneration

sub new {
    my ($class, $fields_ref) = @_;

    if ( $fields_ref->{first_name} ) {
        if ( length $fields_ref->{first_name} < 3 ) {
            die "First name must be longer than 3 symbols!\n";
        }
    }

    return $class->next::method($fields_ref);
}

1;


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)