Subject: | Feature Request: Make MooseColumns work with DBIx Components |
I am experimenting with DBIx-Class-MooseColumns to add the power of
Moose validation to the DBIx storage/retreival facilities.
Initial experiments are promising, but there seems to be a problem with
DBIx::Class components / Moose Roles
It does not appear to be supported.
I will try to explain from a simplified example, which I hope has enough
information.
package MyApp::Component::DateTimeInsert;
use base 'DBIx::Class';
use DateTime;
sub table {
my ( $class, $table ) = @_;
$class->next::method($table);
$class->load_components( 'DynamicDefault', 'Core', );
$class->add_columns(
created_date => {
data_type => 'datetime',
dynamic_default_on_create => sub { DateTime->now(); },
default_value => undef,
},
);
return;
}
Which is then loaded by the other modules:
__PACKAGE__->load_components( '+MyApp::Component::DateTimeInsert',
'UUIDColumns', 'Core', );
In a way the DBIx::Class components act like Moose Roles.
The functionality is inlined into the loading class
This gives a date-time stamp on insertion on every row without any
additional coding. Just load the component in every table that needs it.
I have already verified that I can still load these components from
modules that are using MooseColumns.
Deploying schema to database still works
Accessing the date info still works.
But it does not seem possible to turn the Components into MooseColumns
capable components
e.g. has_created_date
changing the Components code:
package MyApp::Component::DateTimeInsert;
use Moose;
use MooseX::NonMoose;
use namespace::autoclean;
BEGIN {
use DBIx::Class::MooseColumns;
extends 'DBIx::Class';
}
use DateTime;
use MooseX::Types::Moose qw(Str);
sub table {
my ( $class, $table ) = @_;
$class->next::method($table);
$class->load_components( 'DynamicDefault', 'Core', );
has created_date => (
isa => Str,
is => 'rw',
predicate => 'has_created_date',
add_column => {
data_type => 'datetime',
dynamic_default_on_create => sub { DateTime->now(); },
},
);
return;
}
Gives the following error:
DBIx::Class::Schema::throw_exception(): Can't locate object method
"add_column" via package "MyApp::Component::DateTimeInsert"
The DBIx Components extends 'DBIx::Class' But MooseColumns uses extends
'DBIx::Class::Core'
Changing the DBIX Compents to use DBIx::Class::Core instead of
DBIx::Class gives the following
DBIx::Class::Schema::throw_exception(): Can't locate object method
"result_source_instance" via package "MyApp::Component::DateTimeInsert"
Trying to resolve this by using Moose::Role instead of Moose (requires
the removal of 'use MooseX::NonMoose') gives the following:
DBIx::Class::Schema::throw_exception():
DBIx::Class::Row::throw_exception(): MyApp::Component::DateTimeInsert
already has a metaclass, but it does not inherit Moose::Meta::Class
(Moose::Meta::Role=HASH(0xdc69d4)). You cannot make the same thing a
role and a class. Remove either Moose or Moose::Role
Could support for this be added to DBIx-Class-MooseColumns?
Or a example on how to do this be added to the docs?
Thanks.
If there are any questions please let me know.
Tested against:
DBIx-Class-MooseColumns-0.15
SunOS 5.8 Generic_117350-57 sun4u sparc SUNW,Sun-Fire-V240 Solaris
perl version v5.8.7
Note: it required some tinkering to install this module.
As the required DBIx::Class::Schema::PopulateMore module requires
version v5.8.8 in the default install.
It appears however that this is only the case as the autor does not have
access to a 5.8.7 system for testin. All tests passes cleanly.