[Moscow.pm] Mouse: обратный coerce

Тимур Нозадзе timur.nozadze на gmail.com
Вт Сен 24 12:11:51 PDT 2013


Для меня вообще было вопросом, как сделать нормальную запись полей в БД. Т.
е. вот есть объект, часть полей он достаёт из базы, часть -- ещё откуда-то.
Как сделать, чтобы при апдейте поля через сеттер новое значение автоматом
попадало в базу (причём только для нужных полей, тех, которые из базы
достали)? Сеттеры при этом, конечно, хотелось иметь дефолтные, не определяя
их явно в классе.

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

если как бд используется DBIx::Class, у него есть 2хсторонние средства
> inflate/deflate,
>
Если, то, наверное да. :) Но это уже решение на уровне DBIx::Class, а не на
уровне Moose/Mouse.


24 сентября 2013 г., 22:59 пользователь Тимур Нозадзе <
timur.nozadze на gmail.com> написал:

> Подобную задачу пытался на Moose решить недавно. Красивого способа не
> нашёл.
> В итоге сделал конвертацию вручную перед записью в БД:
>
> my $attr = $self->meta->get_attribute($field_name);
> if ( $attr->should_coerce ) {
>     my $constraint = Moose::Util::TypeConstraints::find_type_constraint(
> 'DBField' );
>     $new_value = $constraint->coerce($new_value);
> }
>
> Код не продакшн, больше для знакомства с Moose. Но вроде работал.
>
>
> 24 сентября 2013 г., 22:24 пользователь Ivan Petrov <
> i.petro.77.00 на gmail.com> написал:
>
> имеется выборка из БД
>>
>> {
>>     name => 'name',
>>     point => '{ x: 1, y: 2 }'
>> }
>>
>> далее класс
>>
>> package Point;
>> use Mouse;
>> require JSON::XS;
>>
>> has x   => is => 'ro', isa => 'Num';
>> has y   => is => 'ro', isa => 'Num';
>>
>> sub jstr {
>>     my ($class, $str) = @_;
>>     my $json = JSON::XS->new->decode( $str );
>>     return $class->new(x => $json->{x}, y => $json->{y});
>> }
>>
>> package Obj;
>> use Mouse;
>> use Mouse::Util::TypeConstraints;
>>
>> coerce Point
>>     => from 'Str',
>>     => via sub { Point->jstr( $_) };
>>
>> has name    => is => 'rw', isa => 'Str';
>> has point   => is => 'rw', isa => 'Point', coerce => 1;
>>
>> из БД в поле point приходит нераспакованный JSON.
>>
>> соответственно при помощи coerce мы его распаковываем прозрачно.
>> выборку из БД просто кормим конструктору Obj.
>>
>> все красиво.
>>
>> а теперь как сделать красиво чтобы обратно в БД записать?
>>
>>
>> кроме как сериализационный метод у Point есть какие-то
>> варианты?
>> --
>> Moscow.pm mailing list
>> moscow-pm на pm.org | http://moscow.pm.org
>>
>
>
>
> --
> С уважением, Тимур Нозадзе
>



-- 
С уважением, Тимур Нозадзе
----------- следущая часть -----------
Вложение в формате HTML было извлечено…
URL: <http://mail.pm.org/pipermail/moscow-pm/attachments/20130924/32870ff3/attachment.html>


Подробная информация о списке рассылки Moscow-pm