1 package DBIx::Class::ResultSet::WithMetaData;
8 use Method::Signatures::Simple;
9 extends 'DBIx::Class::ResultSet';
26 has '_hash_modifiers' => (
31 has '_key_modifiers' => (
42 our $VERSION = '1.000002';
46 DBIx::Class::ResultSet::WithMetaData
50 package MyApp::Schema::ResultSet::ObjectType;
53 use MooseX::Method::Signatures;
54 extends 'DBIx::Class::ResultSet::WithMetaData;
56 method with_substr () {
57 return $self->_with_meta_key(
59 return substr(shift->{name}, 0, 3);
69 my $object_type_arrayref = $object_type_rs->with_substr->display();
73 # 'name' => 'Caterwauler McCrae',
78 # 'name' => 'Random Boy Band',
83 # 'name' => 'We Are Goth',
89 Attach metadata to rows by chaining ResultSet methods together. When the ResultSet is
90 flattened to an ArrayRef the metadata is merged with the row hashes to give
91 a combined 'hash-plus-other-stuff' representation.
100 my $new = $self->next::method(@_);
101 foreach my $key (qw/_row_info was_row id_cols _key_modifiers _hash_modifiers/) {
102 alias $new->{$key} = $new->{attrs}{$key};
105 unless ($new->_row_info) {
109 unless ($new->_key_modifiers) {
110 $new->_key_modifiers([]);
112 unless ($new->_hash_modifiers) {
113 $new->_hash_modifiers([]);
116 unless ($new->id_cols && scalar(@{$new->id_cols})) {
117 $new->id_cols([sort $new->result_source->primary_columns]);
127 =item Arguments: none
129 =item Return Value: ArrayRef
133 $arrayref_of_row_hashrefs = $rs->display();
135 This method uses L<DBIx::Class::ResultClass::HashRefInflator> to convert all
136 rows in the ResultSet to HashRefs. Then the subrefs that were added via
137 L</_with_meta_key> or L</_with_meta_hash> are run for each row and the
138 resulting data merged with them.
143 my $rs = $self->search({});
144 # $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
145 $rs->result_class('DBIx::Class::WithMetaData::Inflator');
147 foreach my $row_rep ($rs->all) {
148 my ($row, $row_obj) = @{$row_rep};
149 # THIS BLOCK IS DEPRECATED
150 if (my $info = $self->row_info_for(id => $self->_mk_id(row => $row))) {
151 $row = { %{$row}, %{$info} };
154 foreach my $modifier (@{$rs->_hash_modifiers}) {
155 my $row_hash = $modifier->($row);
156 if (ref $row_hash ne 'HASH') {
157 die 'modifier subref (added via build_metadata) did not return hashref';
160 # simple merge for now, potentially needs to be more complex
161 $row->{$_} = $row_hash->{$_} for keys %{$row_hash};
164 foreach my $params (@{$rs->_key_modifiers}) {
165 my $modifier = $params->{modifier};
166 my $key = $params->{key};
168 if (my $val = $modifier->($row)) {
175 return ($self->was_row) ? $rows[0] : \@rows;
178 =head2 _with_meta_key
182 =item Arguments: key_name => subref($row_hash)
184 =item Return Value: ResultSet
188 $self->_with_meta_key( substr => sub ($row) {
189 return substr(shift->{name}, 0, 3);
192 This method allows you populate a certain key for each row hash at L</display> time.
196 method _with_meta_key ($key, $modifier) {
197 my $rs = $self->search({});
199 die 'build_metadata called without key';
202 unless ($modifier && (ref $modifier eq 'CODE')) {
203 die 'build_metadata called without modifier param';
206 push( @{$rs->_key_modifiers}, { key => $key, modifier => $modifier });
210 =head2 _with_meta_hash
214 =item Arguments: subref($row_hash)
216 =item Return Value: ResultSet
220 $self->_with_meta_hash( sub ($row) {
222 my $return_hash = { substr => substr($row->{name}, 0, 3), substr2 => substr($row->{name}, 0, 4) };
226 Use this method when you want to populate multiple keys of the hash at the same time. If you just want to
227 populate one key, use L</_with_meta_key>.
231 method _with_meta_hash ($modifier) {
232 my $rs = $self->search({});
233 unless ($modifier && (ref $modifier eq 'CODE')) {
234 die 'build_metadata called without modifier param';
237 push( @{$rs->_hash_modifiers}, $modifier );
241 =head2 add_row_info (DEPRECATED)
245 =item Arguments: row => DBIx::Class::Row object, info => HashRef to attach to the row
247 =item Return Value: ResultSet
251 $rs = $rs->add_row_info(row => $row, info => { dates => [qw/mon weds fri/] } );
253 DEPRECATED - this method is quite slow as it requires that you iterate through
254 the resultset each time you want to add metadata. Replaced by L</build_metadata>.
258 method add_row_info (%opts) {
259 my ($row, $id, $info) = map { $opts{$_} } qw/row id info/;
261 warn 'DEPRECATED - add_row_info is deprecated in favour of build_metadata';
263 $id = $self->_mk_id(row => { $row->get_columns });
266 unless ($row || $self->find($id)) {
267 die 'invalid id passed to add_row_info';
270 if (my $existing = $self->_row_info->{$id}) {
271 $info = { %{$existing}, %{$info} };
274 $self->_row_info->{$id} = $info;
278 method row_info_for (%opts) {
280 return $self->_row_info->{$id};
284 method _mk_id (%opts) {
285 my $row = $opts{row};
286 return join('-', map { $row->{$_} } @{$self->id_cols});
291 Luke Saunders <luke.saunders@gmail.com>
295 As usual, thanks to Matt S Trout for the sanity check.
299 This library is free software under the same license as perl itself