Skip to content

Commit

Permalink
working matpath, sweet!
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthur Axel 'fREW' Schmidt committed Apr 12, 2012
1 parent a475e94 commit 8705745
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 14 deletions.
98 changes: 84 additions & 14 deletions lib/DU/Schema/Result/Ingredient.pm
@@ -1,6 +1,8 @@
package DU::Schema::Result::Ingredient;

use DU::Schema::Candy;
use DU::Schema::Candy -components => [
'Helper::Row::OnColumnChange'
];

primary_column id => {
data_type => 'int',
Expand All @@ -13,6 +15,13 @@ column kind_of_id => {
is_nullable => 1,
};

column materialized_path => {
data_type => 'varchar',
is_nullable => 1,
size => 255,
accessor => '_materialized_path',
};

unique_column name => {
data_type => 'nvarchar',
size => 50,
Expand All @@ -23,33 +32,94 @@ column description => {
is_nullable => 1,
};

belongs_to kind_of => '::Ingredient', 'kind_of_id', { join_type => 'left' };
belongs_to direct_kind_of => '::Ingredient', 'kind_of_id', { join_type => 'left' };
has_many direct_kinds => '::Ingredient', 'kind_of_id';
has_many inventory_items => '::InventoryItem', 'ingredient_id';
has_many links_to_drink_ingredients => '::Drink_Ingredient', 'ingredient_id';

belongs_to
sub _set_materialized_path {
my $self = shift;

if ($self->kind_of_id) {
$self->discard_changes;

$self->_materialized_path(
$self->direct_kind_of->_materialized_path . q(/) . $self->id
);
} else {
$self->_materialized_path($self->id)
}
$self->update
}

sub _fix_for_updates {
my ( $self, $old, $new ) = @_;

$self->_set_materialized_path;

$_->_fix_for_updates for $self->direct_kinds->all
}

sub insert {
my $self = shift;

my $ret = $self->next::method;

$ret->_set_materialized_path;

return $ret;
}

after_column_change kind_of_id => {
txn_wrap => 1,
method => '_fix_for_updates',
} for qw(kind_of_id materialized_path);

has_many
kind_of => '::Ingredient',
sub {
my $args = shift;

my $path_separator = q(/);
my $rest = "$path_separator%";

return ({
"$args->{self_alias}.materialized_path" => {
-like => {
-concat => [
{ -ident => "$args->{foreign_alias}.materialized_path" },
$rest
]
my $me = {
"$args->{self_alias}.id" => { -ident => "$args->{foreign_alias}.id" }
};
return ([{
"$args->{self_alias}.materialized_path" => {
-like => \["$args->{foreign_alias}.materialized_path" . ' || ' . '?',
[ {} => $rest ]
],
}
}
},
},
$me
],
$args->{self_rowobj} && {
"$args->{foreign_alias}.id" => {
-in => split qr(/), $args->{self_rowobj}->materialized_path
}
-in => [ split qr(/), $args->{self_rowobj}->_materialized_path ]
},
});
};

has_many
kinds => '::Ingredient',
sub {
my $args = shift;

my $path_separator = q(/);
my $rest = "$path_separator%";

my $me = {
"$args->{self_alias}.id" => { -ident => "$args->{foreign_alias}.id" }
};
return [{
"$args->{foreign_alias}.materialized_path" => {
-like => \["$args->{self_alias}.materialized_path" . ' || ' . '?',
[ {} => $rest ]
],
}
}, $me ]
};

1;
25 changes: 25 additions & 0 deletions t/schema.t
Expand Up @@ -66,4 +66,29 @@ for ($links->all) {
}
is $links->slice(0)->single->ingredient->name, 'Club Soda';

subtest kinds => sub {
my $ings = $s->resultset('Ingredient');

my $rum = $ings->create({ name => 'Rum' });
my $dark_rum = $rum->direct_kinds->create({ name => 'Dark Rum' });
$dark_rum->direct_kinds->create({ name => q(Myers's Jamaican Rum) });
$rum->direct_kinds->create({ name => 'Gold Rum' });
$rum->direct_kinds->create({ name => 'Black Rum' });
$rum->direct_kinds->create({ name => 'Spiced Rum' });

is( $rum->direct_kinds->count, 4, 'direct kinds all created');
is( $rum->kinds->count, 4 + 1 + 1, 'kinds count is correct');
is( $dark_rum->direct_kind_of->name, 'Rum', 'direct_kind_of is correct for dark rum');
$rum->discard_changes; # why do I have to do this?
ok(!$rum->direct_kind_of, 'Rum is not a kind of anything');

my $liquor = $ings->create({ name => 'Liquor' });
$rum->kind_of_id($liquor->id);
$rum->update;
$rum->discard_changes;
$dark_rum->discard_changes;
is( $liquor->kinds->count, 4 + 1 + 1 + 1, 'kinds count for liquor is correct');
is( $dark_rum->kind_of->count, 3, 'dark rum is dark rum, rum, and liquor');
};

done_testing;

0 comments on commit 8705745

Please sign in to comment.