use Catalyst::Controller::DBIC::API::Request;
use namespace::autoclean;
-with 'Catalyst::Controller::DBIC::API::StoredResultSource';
-with 'Catalyst::Controller::DBIC::API::StaticArguments';
-with 'Catalyst::Controller::DBIC::API::RequestArguments' => { static => 1 };
+with 'Catalyst::Controller::DBIC::API::StoredResultSource',
+ 'Catalyst::Controller::DBIC::API::StaticArguments',
+ 'Catalyst::Controller::DBIC::API::RequestArguments' => { static => 1 };
__PACKAGE__->config();
__PACKAGE__->config
( action => { setup => { PathPart => 'artist', Chained => '/api/rpc/rpc_base' } }, # define parent chain action and partpath
- class => 'MyAppDB::Artist', # DBIC schema class
- create_requires => ['name', 'age'], # columns required to create
- create_allows => ['nickname'], # additional non-required columns that create allows
- update_allows => ['name', 'age', 'nickname'], # columns that update allows
- update_allows => ['name', 'age', 'nickname'], # columns that update allows
- select => [qw/name age/], # columns that data returns
- prefetch => ['cds'], # relationships that are prefetched when no prefetch param is passed
- prefetch_allows => [ # every possible prefetch param allowed
+ class => 'MyAppDB::Artist',
+ create_requires => ['name', 'age'],
+ create_allows => ['nickname'],
+ update_allows => ['name', 'age', 'nickname'],
+ update_allows => ['name', 'age', 'nickname'],
+ select => [qw/name age/],
+ prefetch => ['cds'],
+ prefetch_allows => [
'cds',
qw/ cds /,
{ cds => 'tracks' },
- { cds => [qw/ tracks /] }
+ { cds => [qw/ tracks /] },
],
- ordered_by => [qw/age/], # order of generated list
- search_exposes => [qw/age nickname/, { cds => [qw/title year/] }], # columns that can be searched on via list
- data_root => 'data' # defaults to "list" for backwards compatibility
- use_json_boolean => 1, # use JSON::Any::true|false in the response instead of strings
- return_object => 1, # makes create and update actions return the object
+ ordered_by => [qw/age/],
+ search_exposes => [qw/age nickname/, { cds => [qw/title year/] }],
+ data_root => 'data',
+ use_json_boolean => 1,
+ return_object => 1,
);
# Provides the following functional endpoints:
sub generate_rs
{
- my ($self, $c) = @_;
+ #my ($self, $c) = @_;
+ my ($self) = @_;
+
return $self->stored_result_source->resultset;
}
=method_protected list_munge_parameters
list_munge_parameters is a noop by default. All arguments will be passed through without any manipulation. In order to successfully manipulate the parameters before the search is performed, simply access $c->req->search_parameters|search_attributes (ArrayRef and HashRef respectively), which correspond directly to ->search($parameters, $attributes). Parameter keys will be in already-aliased form.
+To store the munged parameters call $c->req->_set_search_parameters($newparams) and $c->req->_set_search_attributes($newattrs).
=cut
sub row_format_output
{
- my ($self, $c, $row) = @_;
+ #my ($self, $c, $row) = @_;
+ my ($self, undef, $row) = @_;
return $row; # passthrough by default
}
foreach my $related_col (@{$allowed_related_cols})
{
- if (my $related_col_value = $related_params->{$related_col}) {
+ if (defined(my $related_col_value = $related_params->{$related_col})) {
$values{$key}{$related_col} = $related_col_value;
}
}
}
# check for multiple values
- if (ref($value) && !($value == JSON::Any::true || $value == JSON::Any::false))
+ if (ref($value) && !(reftype($value) eq reftype(JSON::Any::true)))
{
require Data::Dumper;
die "Multiple values for '${key}': ${\Data::Dumper::Dumper($value)}";
=method_protected update_object_from_params
-update_object_from_params iterates through the params to see if any of them are pertinent to relations. If so it calls L</update_object_relation> with the object, and the relation parameters. Then it calls ->upbdate on the object.
+update_object_from_params iterates through the params to see if any of them are pertinent to relations. If so it calls L</update_object_relation> with the object, and the relation parameters. Then it calls ->update on the object.
=cut
foreach my $key (keys %$params)
{
my $value = $params->{$key};
- if (ref($value) && !($value == JSON::Any::true || $value == JSON::Any::false))
+ if (ref($value) && !(reftype($value) eq reftype(JSON::Any::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);
+ $object->update();
}
=method_protected update_object_relation
{
my ($self, $c, $object, $related_params, $relation) = @_;
my $row = $object->find_related($relation, {} , {});
- $row->update($related_params);
+
+ if ($row) {
+ foreach my $key (keys %$related_params) {
+ my $value = $related_params->{$key};
+ if (ref($value) && !(reftype($value) eq reftype(JSON::Any::true)))
+ {
+ $self->update_object_relation($c, $row, delete $related_params->{$key}, $key);
+ }
+ # accessor = colname
+ elsif ($row->can($key)) {
+ $row->$key($value);
+ }
+ # accessor != colname
+ else {
+ my $accessor = $row->result_source->column_info($key)->{accessor};
+ $row->$accessor($value);
+ }
+ }
+ $row->update();
+ }
+ else {
+ $object->create_related($relation, $related_params);
+ }
}
=method_protected insert_object_from_params
sub insert_object_from_params
{
- my ($self, $c, $object, $params) = @_;
- $object->set_columns($params);
+ #my ($self, $c, $object, $params) = @_;
+ my ($self, undef, $object, $params) = @_;
+
+ my %rels;
+ while (my ($k, $v) = each %{ $params }) {
+ if (ref($v) && !(reftype($v) eq reftype(JSON::Any::true))) {
+ $rels{$k} = $v;
+ }
+ else {
+ $object->set_column($k => $v);
+ }
+ }
+
$object->insert;
+
+ while (my ($k, $v) = each %rels) {
+ $object->create_related($k, $v);
+ }
}
=method_protected delete_objects
sub delete_object
{
- my ($self, $c, $object) = @_;
+ #my ($self, $c, $object) = @_;
+ my ($self, undef, $object) = @_;
$object->delete;
}
sub each_object_inflate
{
- my ($self, $c, $object) = @_;
+ #my ($self, $c, $object) = @_;
+ my ($self, undef, $object) = @_;
- return { $object->get_inflated_columns };
+ return { $object->get_columns };
}
+=method_protected serialize
+
+multiple actions forward to serialize which uses Catalyst::Action::Serialize.
+
+=cut
+
# from Catalyst::Action::Serialize
sub serialize :ActionClass('Serialize') { }
sub push_error
{
my ( $self, $c, $params ) = @_;
- push( @{$c->stash->{_dbic_crud_errors}}, $params->{message} || 'unknown error' );
+ my $error = 'unknown error';
+ if (exists $params->{message}) {
+ $error = $params->{message};
+ # remove newline from die "error message\n" which is required to not
+ # have the filename and line number in the error text
+ $error =~ s/\n$//;
+ }
+ push( @{$c->stash->{_dbic_crud_errors}}, $error);
}
=method_protected get_errors
=head3 page
-Arguments to pass to L<DBIx::Class::ResultSet/rows> when performing search for L</list>.
+Arguments to pass to L<DBIx::Class::ResultSet/page> when performing search for L</list>.
=head1 EXTENDING