Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unique constraints do not work properly across a belongs_to relationship #20

Open
dracos opened this issue May 23, 2019 · 0 comments
Open

Comments

@dracos
Copy link

dracos commented May 23, 2019

If you have a DB model, something like:

__PACKAGE__->add_columns(
  "id", { data_type => "integer", is_auto_increment => 1, is_nullable => 0, sequence => "roles_id_seq" },
  "body_id", { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
  "name", { data_type => "text", is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->add_unique_constraint("roles_body_id_name_key", ["body_id", "name"]);
__PACKAGE__->belongs_to(
  "body", "App::DB::Result::Body", { id => "body_id" },
  { is_deferrable => 0, on_delete => "CASCADE,", on_update => "NO ACTION" },
);

And a matching form (which needs body to work, body_id does not):

has_field 'name' => ( required => 1 );
has_field 'body' => ( type => 'Select', empty_select => 'Select a body', required => 1 );

And your database has three rows:

  1. Body A, name "123"
  2. Body A, name "456"
  3. Body B, name "789"

Then the following happens:

  • Editing row 1 to Body A, name "456" – works fine, you get the "Duplicate value for [_1] unique constraint" error message.
  • Editing row 1 to Body B, name "789" – validation incorrectly passes, it tries to update and dies with a database error.
  • Creating a new entry, Body A, name "123" – validation incorrectly passes, it tries to insert and dies with a database error.

This is because the form column is body but the database field is body_id. Here is the bit of code responsible:

my @values = map {
exists( $value->{$_} ) ? $value->{$_} : undef ||
( $self->item ? $self->item->get_column($_) : undef )
} @columns;

$value will have a body entry, not a body_id entry, from the submitted form. So it always falls back to the item lookup, so on creation that's nothing and on editing the body is the original body not the new one. In both those cases it therefore doesn't find the $value->{body} entry and incorrectly passes validation.

It needs to know how to turn either body_id into body or vice-versa, at the accessor for those columns, not the actual column names, but I'm not sure how best to do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant