Skip to content

Commit

Permalink
Made it work in roles (under Moose 2.x).
Browse files Browse the repository at this point in the history
Now attributes with 'add_column' option can be defined in roles and then
the role can be applied to DBIC result classes (but strictly after a
->table() call..).
  • Loading branch information
mendel committed May 5, 2011
1 parent 185e495 commit de08b73
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 22 deletions.
52 changes: 30 additions & 22 deletions lib/DBIx/Class/MooseColumns/Meta/Role/Attribute.pm
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,48 @@ DBIx::Class::MooseColumns::Meta::Role::Attribute - Attribute metaclass trait for
=cut

has _column_info => (
isa => 'Maybe[HashRef]',
is => 'rw',
);

around new => sub {
my ($orig, $class, $name, %options) = @_;

my $column_info = delete $options{add_column};
$column_info->{accessor} = $options{accessor} if $options{accessor};

my $is_inflated_column;
my $self = $class->$orig($name, %options);

if ($column_info) {
my $target_pkg = $options{definition_context}->{package};

$target_pkg->add_column($name => $column_info);
$self->_column_info($column_info);

# removing the accessor method that CAG installed (otherwise Moose
# complains)
$target_pkg->meta->remove_method($column_info->{accessor} || $name);
return $self;
};

#FIXME respect the API - check for $target_pkg->inflate_column() calls instead of peeking into the guts of the object
if (exists $target_pkg->column_info($name)->{_inflate_info}) {
$is_inflated_column = 1;
}
}
before attach_to_class => sub {
my ($self, $meta) = @_;

my $self = $class->$orig($name, %options);
my $column_info = $self->_column_info
or return;

if ($column_info) {
ensure_all_roles($self,
$is_inflated_column
? 'DBIx::Class::MooseColumns::Meta::Role::Attribute::DBICColumn::Inflated'
: 'DBIx::Class::MooseColumns::Meta::Role::Attribute::DBICColumn'
);
}
my $class = $meta->name;
my $attr_name = $self->name;

return $self;
$class->add_column($attr_name => $column_info);

# removing the accessor method that CAG installed (otherwise Moose
# complains)
$meta->remove_method($column_info->{accessor} || $attr_name);

#FIXME respect the API - check for $class->inflate_column() calls instead of peeking into the guts of the object
my $is_inflated_column
= exists $class->column_info($self->name)->{_inflate_info};

ensure_all_roles($self,
$is_inflated_column
? 'DBIx::Class::MooseColumns::Meta::Role::Attribute::DBICColumn::Inflated'
: 'DBIx::Class::MooseColumns::Meta::Role::Attribute::DBICColumn'
);
};

1;
49 changes: 49 additions & 0 deletions t/30-attr_defined_in_role.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env perl

use strict;
use warnings;

use Test::Most;

use FindBin;
use Path::Class;
use lib dir($FindBin::Bin)->subdir('lib')->stringify;

use Moose::Util qw(apply_all_roles);

# must be a BEGIN b/c the first test is in a BEGIN, too :-(
BEGIN {
require Moose;
plan skip_all => 'Using DBIx::Class::MooseColumns in roles is not supported under Moose 1.x'
if $Moose::VERSION < 1.99;
}

# test for the role being applied smoothly

BEGIN {
require TestSchema::Result::CD;
lives_and {
warnings_are {
apply_all_roles('TestSchema::Result::CD', 'TestSchema::Role::HasTitle');
} [];
} "applying the role to a result class does not throw nor warn";
}

use Test::DBIx::Class;

fixtures_ok 'basic', 'installed the basic fixtures from configuration files';

# tests for ->add_column() being called for an attribute defined in a role

{
lives_and {
cmp_deeply(
Schema->resultset('CD')->result_source->column_info('title'),
superhashof({
is_nullable => 1,
})
);
} "column_info of 'title' contains ('is_nullable' => 1)";
}

done_testing;
16 changes: 16 additions & 0 deletions t/lib/TestSchema/Result/CD.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package TestSchema::Result::CD;

use Moose;
use MooseX::NonMoose;
use namespace::autoclean;

extends 'DBIx::Class::Core';

__PACKAGE__->table('cd');

__PACKAGE__->add_column('cd_id');

# this class is intentionally left immutable (so that we can apply the role
# later)

1;
17 changes: 17 additions & 0 deletions t/lib/TestSchema/Role/HasTitle.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package TestSchema::Role::HasTitle;

use Moose::Role;
use namespace::autoclean;

use DBIx::Class::MooseColumns;

# used for testing if the attribute works on the class this role was applied to
has title => (
isa => 'Maybe[Str]',
is => 'rw',
add_column => {
is_nullable => 1,
},
);

1;

0 comments on commit de08b73

Please sign in to comment.