Created
January 5, 2018 08:57
-
-
Save mrenvoize/debbcfacc5c4e3dc75e813410b3f868b to your computer and use it in GitHub Desktop.
Multi-create Fun
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
my $list_changeResult = $c->db->resultset('ListChange')->create( | |
{ | |
list_id => $list_id, | |
request => [{requester_id => $requester_id, assignee_id => $assignee_id, status => 'new'}], | |
message => { | |
buffer_id => $list_id, | |
user_id => $requester_id, | |
text => "Priority tag '$tag' was removed from the system.", | |
important => 1 | |
} | |
} | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use utf8; | |
package Rebus::Schema::Result::ListChange; | |
=head1 NAME | |
Rebus::Schema::Result::ListChange | |
=cut | |
use strict; | |
use warnings; | |
use base 'DBIx::Class::Core'; | |
=head1 COMPONENTS LOADED | |
=over 4 | |
=item * L<Helper::Row::NumifyGet> | |
=back | |
=cut | |
__PACKAGE__->load_components(qw( Helper::Row::NumifyGet )); | |
=head1 TABLE: C<list_changes> | |
=cut | |
__PACKAGE__->table("list_changes"); | |
=head1 ACCESSORS | |
=head2 id | |
data_type: 'integer' | |
is_auto_increment: 1 | |
is_nullable: 0 | |
is_numeric: 1 | |
=head2 list_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 1 | |
is_numeric: 1 | |
=head2 message_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 1 | |
is_numeric: 1 | |
=cut | |
__PACKAGE__->add_columns( | |
"id", {data_type => "integer", is_auto_increment => 1, is_nullable => 0, is_numeric => 1}, | |
"list_id", {data_type => "integer", is_foreign_key => 1, is_nullable => 0, is_numeric => 1}, | |
"message_id", {data_type => "integer", is_foreign_key => 1, is_nullable => 1, is_numeric => 1}, | |
); | |
=head1 PRIMARY KEY | |
=over 4 | |
=item * L </id> | |
=back | |
=cut | |
__PACKAGE__->set_primary_key("id"); | |
=head1 RELATIONS | |
=head2 request | |
Type: has_one | |
Related object: L<Rebus::Schema::Result::Request> | |
=cut | |
__PACKAGE__->has_one( | |
"request", | |
"Rebus::Schema::Result::Request", | |
{"foreign.list_change_id" => "self.id"}, | |
{is_foreign_key_constraint => 1, is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE"}, | |
); | |
=head2 list | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::List> | |
=cut | |
__PACKAGE__->belongs_to( | |
"list", 'Rebus::Schema::Result::List', | |
{"foreign.id" => "self.list_id"}, | |
{on_delete => "CASCADE", on_update => "CASCADE", "is_foreign_key_constraint" => 1}, | |
); | |
=head2 buffer | |
Type: might_have | |
Related object: L<Rebus::Schema::Result::Buffer> | |
=cut | |
__PACKAGE__->might_have( | |
"buffer", | |
'Rebus::Schema::Result::Buffer', | |
{"foreign.list_id" => "self.list_id"}, | |
{join_type => "left", is_foreign_key_constraint => 0, cascade_delete => 0}, | |
); | |
=head2 message | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::Buffermessage> | |
=cut | |
__PACKAGE__->belongs_to( | |
"message", | |
'Rebus::Schema::Result::Buffermessage', | |
{'foreign.id' => 'self.message_id'}, | |
{'join_type' => 'left', 'on_delete' => 'SET NULL'}, | |
); | |
1; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use utf8; [258/9963] | |
package Rebus::Schema::Result::Request; | |
=head1 NAME | |
Rebus::Schema::Result::Request | |
=cut | |
use strict; | |
use warnings; | |
use base 'DBIx::Class::Core'; | |
=head1 COMPONENTS LOADED | |
=over 4 | |
=item * L<DBIx::Class::InflateColumn::DateTime> | |
=item * L<Helper::Row::NumifyGet> | |
=back | |
=cut | |
__PACKAGE__->load_components(qw(InflateColumn::DateTime Helper::Row::NumifyGet)); | |
=head1 TABLE: C<request> | |
=cut | |
__PACKAGE__->table("requests"); | |
=head1 ACCESSORS | |
=head2 id | |
data_type: 'integer' | |
is_auto_increment: 1 | |
is_nullable: 0 | |
is_numeric: 1 | |
=head2 requester_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 0 | |
is_numeric: 1 | |
=head2 assignee_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 1 | |
is_numeric: 1 | |
=head2 status | |
data_type: 'text' | |
is_foreign_key: 1 | |
is_nullable: 0 | |
=head2 updated | |
data_type: 'timestamp' | |
datetime_undef_if_invalid: 1 | |
default_value: current_timestamp | |
is_nullable: 0 | |
retrieve_on_insert: 1 | |
=head2 created | |
data_type: 'timestamp' | |
datetime_undef_if_invalid: 1 | |
default_value: current_timestamp | |
is_nullable: 0 | |
retrieve_on_insert: 1 | |
[179/9963] | |
=head2 material_change_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 1 | |
is_numeric: 1 | |
=head2 material_copy_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 1 | |
is_numeric: 1 | |
=head2 list_change_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 1 | |
is_numeric: 1 | |
=head2 buffer_submission_id | |
data_type: 'integer' | |
is_foreign_key: 1 | |
is_nullable: 1 | |
is_numeric: 1 | |
=cut | |
__PACKAGE__->add_columns( | |
"id", | |
{data_type => "integer", is_auto_increment => 1, is_nullable => 0, is_numeric => 1}, | |
"requester_id", | |
{data_type => "integer", is_foreign_key => 1, is_nullable => 0, is_numeric => 1}, | |
"assignee_id", | |
{data_type => "integer", is_foreign_key => 1, is_nullable => 1, is_numeric => 1}, | |
"status", | |
{data_type => "text", is_nullable => 0,}, | |
"updated", | |
{ | |
data_type => "timestamp", | |
datetime_undef_if_invalid => 1, | |
default_value => \"current_timestamp", | |
is_nullable => 0, | |
retrieve_on_insert => 1 | |
}, | |
"created", | |
{ | |
data_type => "timestamp", | |
datetime_undef_if_invalid => 1, | |
default_value => \"current_timestamp", | |
is_nullable => 0, | |
retrieve_on_insert => 1 | |
}, | |
'material_change_id', | |
{data_type => "integer", is_foreign_key => 1, is_nullable => 1, is_numeric => 1, default_value => \"null"}, | |
'material_copy_id', | |
{data_type => "integer", is_foreign_key => 1, is_nullable => 1, is_numeric => 1, default_value => \"null"}, | |
'list_change_id', | |
{data_type => "integer", is_foreign_key => 1, is_nullable => 1, is_numeric => 1, default_value => \"null"}, | |
'buffer_submission_id', | |
{data_type => "integer", is_foreign_key => 1, is_nullable => 1, is_numeric => 1, default_value => \"null"}, | |
); | |
=head1 PRIMARY KEY | |
=over 4 | |
=item * L</id> | |
=back | |
=cut | |
__PACKAGE__->set_primary_key("id"); | |
=head1 CONSTRAINTS | |
=head2 material_change | |
Type: Unique | |
=cut | |
__PACKAGE__->add_unique_constraint(material_change => [qw/material_change_id/]); | |
=head2 material_copy | |
Type: Unique | |
=cut | |
__PACKAGE__->add_unique_constraint(material_copy => [qw/material_copy_id/]); | |
=head2 list_change | |
Type: Unique | |
=cut | |
__PACKAGE__->add_unique_constraint(list_change => [qw/list_change_id/]); | |
=head2 buffer_submission | |
Type: Unique | |
=cut | |
__PACKAGE__->add_unique_constraint(buffer_submission => [qw/buffer_submission_id/]); | |
=head2 Multiple Table Inheritance - XOR | |
=over 4 | |
=item * material_change | |
=item * material_copy | |
=item * list_change | |
=item * buffer_submission | |
=back | |
=cut | |
sub sqlt_deploy_hook { | |
my ($self, $sqlt_table) = @_; | |
return $sqlt_table->add_constraint( | |
type => 'CHECK', | |
name => 'requests_xor', | |
expression => | |
"(material_copy_id IS NOT NULL)::integer + (buffer_submission_id IS NOT NULL)::integer + (list_change_id IS NOT NULL)::integer + (material_change_id IS NOT NULL)::integer = 1" | |
); | |
} | |
=head1 SPECIAL ACCESSORS | |
=head2 type | |
Name: type | |
=cut | |
sub type { | |
my $self = shift; | |
return 'change' if defined($self->material_change_id); | |
return 'copy' if defined($self->material_copy_id); | |
return 'buffer_submission' if defined($self->buffer_submission_id); | |
return 'list_change' if defined($self->list_change_id); | |
return; | |
} | |
=head1 RELATIONS | |
=head2 assignee | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::User> | |
=cut | |
__PACKAGE__->belongs_to( | |
"assignee" => "Rebus::Schema::Result::User", | |
{id => "assignee_id"}, {is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT", join_type => "left"}, | |
); | |
=head2 requester | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::User> | |
=cut | |
__PACKAGE__->belongs_to( | |
"requester" => "Rebus::Schema::Result::User", | |
{id => "requester_id"}, {is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT"}, | |
); | |
=head2 request_actions | |
Type: has_many | |
Related object: L<Rebus::Schema::Result::RequestAction> | |
=cut | |
__PACKAGE__->has_many( | |
"request_actions" => "Rebus::Schema::Result::RequestAction", | |
{"foreign.request_id" => "self.id"}, {cascade_copy => 0, cascade_delete => 1}, | |
); | |
=head2 material_copy | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::MaterialCopy> | |
=cut | |
__PACKAGE__->belongs_to( | |
'material_copy', | |
'Rebus::Schema::Result::MaterialCopy', | |
{'foreign.id' => 'self.material_copy_id'}, | |
{join_type => 'left', is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT"}, | |
); | |
=head2 material_change | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::MaterialChange> | |
=cut | |
__PACKAGE__->belongs_to( | |
'material_change', | |
'Rebus::Schema::Result::MaterialChange', | |
{'foreign.id' => 'self.material_change_id'}, | |
{join_type => 'left', is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT"}, | |
); | |
=head2 buffer_submission | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::BufferSubmission> | |
=cut | |
__PACKAGE__->belongs_to( | |
'buffer_submission', | |
'Rebus::Schema::Result::BufferSubmission', | |
{'foreign.id' => 'self.buffer_submission_id'}, | |
{join_type => 'left', is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT"}, | |
); | |
=head2 list_change | |
Type: belongs_to | |
Related object: L<Rebus::Schema::Result::ListChange> | |
=cut | |
__PACKAGE__->belongs_to( | |
'list_change', | |
'Rebus::Schema::Result::ListChange', | |
{'foreign.id' => 'self.list_change_id'}, | |
{join_type => 'left', is_deferrable => 1, on_delete => "RESTRICT", on_update => "RESTRICT"}, | |
); | |
1; |
@mrenvoize I am getting the same error ("requires a hashref as argument") --- were you able to figure it out? Thanks!
Edit I posted too soon :) . request
is a has_one
relationship, so the arrayref should not be used.
In my case, I had a singular relationship as well (belongs_to
), so it's a hashref, not an arrayref. Per this, it's only an arrayref for has_many
relationships.
For any future readers, my example was:
In the Result class:
__PACKAGE__->belongs_to(
'admin_role',
'Foo::Schema::Result::Role',
{ 'foreign.id' => 'self.admin_role_id' },
);
When creating:
$rs->create({
name => 'Foo',
admin_role => { role_name => 'Foo role' },
});
The key for the related-row creation was admin_role
(the relationship/accessor name), NOT admin_role_id
(the actual foreign-key name).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's the code in Controller-Priority.pm that fails to run and I believe it's the
request
relation that's the problem.I initially tried using a hashref instead of an arrayref which resulted in the 'request' row being created first which causes a check constraint to fail (check constraints can't be deferred in postgres as far as I'm aware :( ). Following this through I noted that the docs actually state one should use an arrayref for a has_one/has_many relationship for multi-create and hence I switched it, but this leads to the error below: