my \$rs = shift->${dm_name}->related_resultset('${attr_name}');
return ${isa}->new(_source_resultset => \$rs);
}";
- } elsif( $rel_accessor eq 'single') {
+ } elsif( $rel_accessor eq 'single' || $rel_accessor eq 'filter' ) {
#belongs_to
#type constraint is the foreign IM object, default inflates it
my $isa = $attr_opts{isa} = $self->class_name_from_source_name($parent_class, $rel_moniker);
$attr_opts{isa} = $from_attr->_isa_metadata;
$attr_opts{default} = eval "sub{ shift->${dm_name}->${reader} }";
}
-
return \%attr_opts;
};
L<DBIx::Class> or don't have a schema handy, now is a good time to go through
L<DBIx::Class::Manual::Intro> to get a schema set up.
+It is important that your Result-objects implement the meta-protocol of Moose
+One way to achive that is to do the following:
+
+ package MyApp::Schema::Result::Bar;
+ use base 'DBIx::Class';
+ use Moose;
+
+ has 'name' => (isa => 'Str', required => 1);
+
+ use namespace::clean -except => [ 'meta' ];
+
+ __PACKAGE__->load_components(qw(Core));
+ __PACKAGE__->table('bar');
+ __PACKAGE__->add_columns(
+ name => {
+ data_type => 'varchar',
+ size => 255,
+ is_nullable => 0,
+ }
+ );
+ __PACKAGE__->primary_key('name');
+ 1;
+
+Once you have your schema set up like that, you can create the InferfaceModel:
+
package MyApp::InterfaceModel::DBIC;
use base 'Reaction::InterfaceModel::Object';
1;
+Then you create a MyApp::Model that uses this InferfaceModel:
+
+ package Myapp::Model::IM;
+
+
+ use Reaction::Class;
+
+ class IM is 'Catalyst::Model::Reaction::InterfaceModel::DBIC', which {
+
+ };
+
+ 1;
+
=head2 Controllers
+=head3 Root controller
+
Your Reaction application must have a Root controller which inherits from
C<Reaction::UI::Controller::Root>.
1;
+=head3 Individual controllers
+
+For each Collection(table?) in your DB, you need to create a controller
+
+ package MyApp::Controller::Foo;
+
+ use base 'Reaction::UI::Controller::Collection::CRUD';
+ use Reaction::Class;
+
+ __PACKAGE__->config(
+ model_name => 'IM', # This corresponds to the name of the MyApp::Model you created earlier
+ collection_name => 'Foo', # Name of one of the sources in your InterfaceModel
+ action => { base => { Chained => '/base', PathPart => 'foo' } },
+ );
+
+ 1;
+
XX TODO
=head2 View
+One of the views in your application should look something like this:
+
+ package MyApp::View::TT;
+
+ use Reaction::Class;
+
+ class TT is 'Reaction::UI::View::TT', which {
+
+ };
+
+ 1;
+
+ __END__;
+
+
XX TODO
=head1 SEE ALSO
use Reaction::UI::LayoutSet;
use Reaction::UI::RenderingContext;
use File::ShareDir;
+use File::Basename;
use aliased 'Path::Class::Dir';
my $skin_name = $self->name;
if ($skin_name =~ s!^/(.*?)/!!) {
my $dist = $1;
- $args->{skin_base_dir} =
- Dir->new(File::ShareDir::dist_dir($dist))
- ->subdir('skin');
+ $args->{skin_base_dir} = eval {
+ Dir->new(File::ShareDir::dist_dir($dist))
+ ->subdir('skin');
+ };
+ if ($@) {
+ # No installed Reaction
+ my $file = __FILE__;
+ my $dir = Dir->new(dirname($file));
+ my $skin_base;
+ while ($dir->parent) {
+ if (-d $dir->subdir('share') && -d $dir->subdir('share')->subdir('skin')) {
+ $skin_base = $dir->subdir('share')->subdir('skin');
+ last;
+ }
+ $dir = $dir->parent;
+ }
+ confess "could not find skinbase by recursion. ended up at $dir, from $file"
+ unless $skin_base;
+ $args->{skin_base_dir} = $skin_base;
+ }
}
my $base = $args->{skin_base_dir}->subdir($skin_name);
confess "No such skin base directory ${base}"