use CGI::Expand ();
use DBIx::Class::ResultClass::HashRefInflator;
-use JSON ();
+use JSON::MaybeXS ();
use Test::Deep::NoTest('eq_deeply');
use MooseX::Types::Moose(':all');
use Moose::Util;
use Scalar::Util( 'blessed', 'reftype' );
use Try::Tiny;
use Catalyst::Controller::DBIC::API::Request;
+use DBIx::Class::ResultSet::RecursiveUpdate;
use namespace::autoclean;
has '_json' => (
is => 'ro',
- isa => 'JSON',
+ isa => JSON::MaybeXS::JSON(),
lazy_build => 1,
);
sub _build__json {
# no ->utf8 here because the request params get decoded by Catalyst
- return JSON->new;
+ return JSON::MaybeXS->new;
}
with 'Catalyst::Controller::DBIC::API::StoredResultSource',
? [ $related_source->columns ]
: $allowed_fields;
- foreach my $related_col ( @{$allowed_related_cols} ) {
- if (defined(
- my $related_col_value =
- $related_params->{$related_col}
- )
- )
- {
- $values{$key}{$related_col} = $related_col_value;
+ if (ref($related_params) && reftype($related_params) eq 'ARRAY') {
+ my @related_data;
+ for my $related_param (@$related_params) {
+ my %data;
+ foreach my $related_col ( @{$allowed_related_cols} ) {
+ if (defined(
+ my $related_col_value =
+ $related_param->{$related_col}
+ )
+ ) {
+ $data{$related_col} = $related_col_value;
+ }
+ }
+ push @related_data, \%data;
+ }
+ $values{$key} = \@related_data;
+ }
+ else {
+ foreach my $related_col ( @{$allowed_related_cols} ) {
+ if (defined(
+ my $related_col_value =
+ $related_params->{$related_col}
+ )
+ ) {
+ $values{$key}{$related_col} = $related_col_value;
+ }
}
}
}
}
# check for multiple values
- if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) )
+ if ( ref($value) && !( reftype($value) eq reftype(JSON::MaybeXS::true) ) )
{
require Data::Dumper;
die
sub update_object_from_params {
my ( $self, $c, $object, $params ) = @_;
- foreach my $key ( keys %$params ) {
- my $value = $params->{$key};
- if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) ) {
- $self->update_object_relation( $c, $object,
- delete $params->{$key}, $key );
- }
-
- # accessor = colname
- elsif ( $object->can($key) ) {
- $object->$key($value);
- }
-
- # accessor != colname
- else {
- my $accessor =
- $object->result_source->column_info($key)->{accessor};
- $object->$accessor($value);
- }
- }
-
- $object->update();
-}
+ $params = {%$params, %{$object->ident_condition}};
-=method_protected update_object_relation
-
-update_object_relation finds the relation to the object, then calls ->update
-with the specified parameters.
-
-=cut
-
-sub update_object_relation {
- my ( $self, $c, $object, $related_params, $relation ) = @_;
- my $row = $object->find_related( $relation, {}, {} );
-
- if ($row) {
- foreach my $key ( keys %$related_params ) {
- my $value = $related_params->{$key};
- if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) )
- {
- $self->update_object_relation( $c, $row,
- delete $related_params->{$key}, $key );
- }
-
- # accessor = colname
- elsif ( $row->can($key) ) {
- $row->$key($value);
- }
+ my $updated_object =
+ DBIx::Class::ResultSet::RecursiveUpdate::Functions::recursive_update(
+ resultset => $c->req->current_result_set,
+ # unknown_params_ok => 1,
+ updates => $params,
+ );
- # accessor != colname
- else {
- my $accessor =
- $row->result_source->column_info($key)->{accessor};
- $row->$accessor($value);
- }
- }
- $row->update();
- }
- else {
- $object->create_related( $relation, $related_params );
- }
+ # replace request object with updated one for response
+ my $vals = $c->req->get_object(0)->[1];
+ $c->req->clear_objects;
+ $c->req->add_object( [ $updated_object, $vals ] );
}
=method_protected insert_object_from_params
my %rels;
while ( my ( $key, $value ) = each %{$params} ) {
- if ( ref($value) && !( reftype($value) eq reftype(JSON::true) ) ) {
+ if ( ref($value) && !( reftype($value) eq reftype(JSON::MaybeXS::true) ) ) {
$rels{$key} = $value;
}
$object->insert;
while ( my ( $k, $v ) = each %rels ) {
- $object->create_related( $k, $v );
+ if (reftype($v) eq 'ARRAY') {
+ foreach my $next_v ( @$v ) {
+ $object->create_related($k, $next_v);
+ }
+ }
+ else {
+ $object->create_related($k => $v);
+ }
}
}
if ( $c->res->status == 200 ) {
$c->stash->{ $self->stash_key }->{success} =
- $self->use_json_boolean ? JSON::true : 'true';
+ $self->use_json_boolean ? JSON::MaybeXS::true : 'true';
if ( $self->return_object
&& $c->req->has_objects
&& ! exists $c->stash->{ $self->stash_key }->{ $self->data_root } ) {
}
else {
$c->stash->{ $self->stash_key }->{success} =
- $self->use_json_boolean ? JSON::false : 'false';
+ $self->use_json_boolean ? JSON::MaybeXS::false : 'false';
$c->stash->{ $self->stash_key }->{messages} = $self->get_errors($c)
if $self->has_errors($c);
=head3 use_json_boolean
By default, the response success status is set to a string value of "true" or
-"false". If this attribute is true, JSON's true() and false() will be used
-instead. Note, this does not effect other internal processing of boolean values.
+"false". If this attribute is true, JSON::MaybeXS's true() and false() will be
+used instead. Note, this does not effect other internal processing of boolean
+values.
=head3 count_arg, page_arg, select_arg, search_arg, grouped_by_arg, ordered_by_arg, prefetch_arg, as_arg, total_entries_arg
and its role system to refactor functionality out into self-contained roles.
To this end, internally, this module now understands JSON boolean values (as
-represented by the JSON module) and will Do The Right Thing in handling those
-values. This means you can have ColumnInflators installed that can covert
-between JSON booleans and whatever your database wants for boolean values.
+represented by the JSON::MaybeXS module) and will Do The Right Thing in
+handling those values. This means you can have ColumnInflators installed that
+can covert between JSON booleans and whatever your database wants for boolean
+values.
Validation for various *_allows or *_exposes is now accomplished via
Data::DPath::Validator with a lightly simplified, via a subclass of