new component to make m2ms introspectables so we can hint the reflector
[catagits/Reaction.git] / lib / Reaction / InterfaceModel / Collection / DBIC / Role / Base.pm
1 package Reaction::InterfaceModel::Collection::DBIC::Role::Base;
2
3 use Reaction::Role;
4 use Scalar::Util qw/blessed/;
5 use Class::MOP;
6
7 # WARNING - DANGER: this is just an RFC, please DO NOT USE YET
8
9 role Base, which {
10
11   has '_source_resultset' => (
12                              is => 'ro',
13                              required => 1,
14                              isa => 'DBIx::Class::ResultSet',
15                             );
16
17   has 'member_type' => (
18                         is => 'rw', 
19                         isa => 'ClassName',  
20                         required => 1,
21                         builder => '_build_member_type',
22                         clearer => 'clear_member_type',
23                         predicate => 'has_member_type',
24                        );
25
26
27   #implements BUILD => as {
28   #  my $self = shift;
29   #  Class::MOP::load_class($self->_im_class);
30   #  confess "_im_result_class must be a Reaction::InterfaceModel::Object"
31   #    unless $self->_im_class->isa("Reaction::InterfaceModel::Object");
32   #  confess "_im_result_class must have an inflate_result method"
33   #    unless $self->_im_class->can("inflate_result");
34   #};
35
36
37
38   #Oh man. I have a bad feeling about this one.
39   implements _build_member_type => as {
40     my $self = shift;
41     my $class = blessed($self) || $self;
42     $class =~ s/::Collection$//;
43     return $class;
44   };
45
46   implements _build__collection_store => as {
47     my $self = shift;
48     [ $self->_source_resultset->search({}, {result_class => $self->member_type})->all ];
49   };
50
51   implements clone => as {
52     my $self = shift;
53     my $rs = $self->_source_resultset; #->search_rs({});
54     #should the clone include the arrayref of IM::Objects too?
55     return (blessed $self)->new(
56                                 _source_resultset => $rs,
57                                 member_type => $self->member_type, @_
58                                );
59   };
60
61   implements count_members => as {
62     my $self = shift;
63     $self->_source_resultset->count;
64   };
65
66   implements add_member => as {
67     confess "Not yet implemented";
68   };
69
70   implements remove_member => as {
71     confess "Not yet implemented";
72   };
73
74
75   implements page => as {
76     my $self = shift;
77     my $rs = $self->_source_resultset->page(@_);
78     return (blessed $self)->new(
79                                 _source_resultset => $rs,
80                                 member_type => $self->member_type,
81                                );
82   };
83
84   implements pager => as {
85     my $self = shift;
86     return $self->_source_resultset->pager(@_);
87   };
88
89 };
90
91 1;
92
93
94 =head1 NAME
95
96 Reaction::InterfaceModel::Collection::DBIC::Role::Base
97
98 =head1 DESCRIPTION
99
100 Provides methods to allow a collection to be populated by a L<DBIx::Class::ResultSet>
101
102 =head1 Attributes
103
104 =head2 _source_resultset
105
106 Required, Read-only. Contains the L<DBIx::Class::ResultSet> used to populate the
107 collection.
108
109 =head2 member_type
110
111 Read-only, lazy_build. The name of the IM Object Class that the resultset inside this
112 collection will inflate to. Predicate: C<has_member_type>
113
114 =head1 METHODS
115
116 =head2 clone
117
118 Returns a clone of the current collection, complete with a cloned C<_source_resultset>
119
120 =head2 count_members
121
122 Returns the number of items found by the ResultSet
123
124 =head2 add_member
125
126 =head2 remove_member
127
128 These will die as they have not been implemented yet.
129
130 =head1 PRIVATE METHODS
131
132 =head2 _build_im_class
133
134 Will attempt to remove the suffix "Collection" from the current class name and return
135 that. I.e. C<MyApp::MyIM::Roles::Collection> would return C<MyApp::MyIM::Roles>
136
137 =head2 _build_collection_store
138
139 Replace the default builder to populate the collection with all results returned by the
140 resultset.
141
142 =head1 AUTHORS
143
144 See L<Reaction::Class> for authors.
145
146 =head1 LICENSE
147
148 See L<Reaction::Class> for the license.
149
150 =cut