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.000000';
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 $self->build_metadata( modifier => sub () {
59 $row->{substr} = substr($row->{name}, 0, 3);
70 my $object_type_arrayref = $object_type_rs->with_substr->display();
74 # 'name' => 'Caterwauler McCrae',
79 # 'name' => 'Random Boy Band',
84 # 'name' => 'We Are Goth',
90 Attach metadata to rows by chaining ResultSet methods together. When the ResultSet is
91 flattened to an ArrayRef the attached metadata is merged with the row hashes to give
92 a combined 'hash-plus-other-stuff' representation.
101 my $new = $self->next::method(@_);
102 foreach my $key (qw/_row_info was_row id_cols _key_modifiers _hash_modifiers/) {
103 alias $new->{$key} = $new->{attrs}{$key};
106 unless ($new->_row_info) {
110 unless ($new->_key_modifiers) {
111 $new->_key_modifiers([]);
113 unless ($new->_hash_modifiers) {
114 $new->_hash_modifiers([]);
117 unless ($new->id_cols && scalar(@{$new->id_cols})) {
118 $new->id_cols([sort $new->result_source->primary_columns]);
128 =item Arguments: none
130 =item Return Value: ArrayRef
134 $arrayref_of_row_hashrefs = $rs->display();
136 This method uses L<DBIx::Class::ResultClass::HashRefInflator> to convert all
137 rows in the ResultSet to HashRefs. These are then merged with any metadata
138 that had been attached to the rows using L</add_row_info>.
143 my $rs = $self->search({});
144 $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
146 foreach my $row ($rs->all) {
147 # THIS BLOCK IS DEPRECATED
148 if (my $info = $self->row_info_for(id => $self->_mk_id(row => $row))) {
149 $row = { %{$row}, %{$info} };
152 foreach my $modifier (@{$rs->_hash_modifiers}) {
153 my $row_hash = $modifier->($row);
154 if (ref $row_hash ne 'HASH') {
155 die 'modifier subref (added via build_metadata) did not return hashref';
158 # simple merge for now, potentially needs to be more complex
159 $row->{$_} = $row_hash->{$_} for keys %{$row_hash};
162 foreach my $params (@{$rs->_key_modifiers}) {
163 my $modifier = $params->{modifier};
164 my $key = $params->{key};
166 if (my $val = $modifier->($row)) {
173 return ($self->was_row) ? $rows[0] : \@rows;
176 =head2 _with_meta_key
180 =item Arguments: key_name => subref($row_hash)
182 =item Return Value: ResultSet
186 $self->_with_meta_key( substr => sub ($row) {
187 return substr(shift->{name}, 0, 3);
190 This method allows you populate a certain key for each row hash at L</display> time.
194 method _with_meta_key ($key, $modifier) {
195 my $rs = $self->search({});
197 die 'build_metadata called without key';
200 unless ($modifier && (ref $modifier eq 'CODE')) {
201 die 'build_metadata called without modifier param';
204 push( @{$rs->_key_modifiers}, { key => $key, modifier => $modifier });
208 =head2 _with_meta_hash
212 =item Arguments: subref($row_hash)
214 =item Return Value: ResultSet
218 $self->_with_meta_hash( sub ($row) {
220 my $return_hash = { substr => substr($row->{name}, 0, 3), substr2 => substr($row->{name}, 0, 4) };
224 Use this method when you want to populate multiple keys of the hash at the same time. If you just want to
225 populate one key, use L</_with_meta_key>.
229 method _with_meta_hash ($modifier) {
230 my $rs = $self->search({});
231 unless ($modifier && (ref $modifier eq 'CODE')) {
232 die 'build_metadata called without modifier param';
235 push( @{$rs->_hash_modifiers}, $modifier );
239 =head2 add_row_info (DEPRECATED)
243 =item Arguments: row => DBIx::Class::Row object, info => HashRef to attach to the row
245 =item Return Value: ResultSet
249 $rs = $rs->add_row_info(row => $row, info => { dates => [qw/mon weds fri/] } );
251 DEPRECATED - this method is quite slow as it requires that you iterate through
252 the resultset each time you want to add metadata. Replaced by L</build_metadata>.
256 method add_row_info (%opts) {
257 my ($row, $id, $info) = map { $opts{$_} } qw/row id info/;
259 warn 'DEPRECATED - add_row_info is deprecated in favour of build_metadata';
261 $id = $self->_mk_id(row => { $row->get_columns });
264 unless ($row || $self->find($id)) {
265 die 'invalid id passed to add_row_info';
268 if (my $existing = $self->_row_info->{$id}) {
269 $info = { %{$existing}, %{$info} };
272 $self->_row_info->{$id} = $info;
276 method row_info_for (%opts) {
278 return $self->_row_info->{$id};
282 method _mk_id (%opts) {
283 my $row = $opts{row};
284 return join('-', map { $row->{$_} } @{$self->id_cols});
289 Luke Saunders <luke.saunders@gmail.com>
293 As usual, thanks to Matt S Trout for the sanity check.
297 This library is free software under the same license as perl itself