DBIx::...archOr(3pm)

πŸ“¦
version 2.037000 Β· 5 versions
, in debian trixie, ubuntu resolute, ubuntu stonking

πŸ’– DBIx::Class::Helper::ResultSet::SearchOr πŸ’–

okay bestie, welcome to the man page for DBIx::Class::Helper::ResultSet::SearchOr β€” yes it's one of those long-ass Perl module names, it's from the User Contributed Perl Documentation collection, and no I will not be shortening it for you. it's giving ✨combine your ResultSet searches with OR✨. let's go.


✨ SYNOPSIS ✨

package MyApp::Schema::ResultSet::Tests;

use parent 'DBIx::Class::ResultSet';

__PACKAGE__->load_components(qw(Helper::ResultSet::IgnoreWantarray Helper::ResultSet::SearchOr));

sub failed {
  my $self = shift;

  my $me = $self->current_source_alias;

  $self->search({ "$me.passed" => '0' });
}

sub untested {
  my $self = shift;

  my $me = $self->current_source_alias;

  $self->search({ "$me.passed" => undef });
}

sub not_passed {
  my $self = shift;

  my $me = $self->current_source_alias;

  $self->search_or([$self->failed, $self->untested]);
}

1;

like. look at that. failed and untested are just vibing as normal searches and then not_passed is like "bestie what if OR" and search_or is like say less πŸ’…


🌸 DESCRIPTION 🌸

okay so real talk, imo the single most iconic thing about DBIx::Class is that you can chain ResultSet searches. that's the whole personality. BUT πŸ’€ β€” this gets messy when you need to reuse multiple ResultSet methods as… well… or's. the old way I used to sneak around this was:

$rs->foo->union([ $rs->bar]);

and like, yeah, it works, but it starts generating some absolutely hairy SQL, fast, no cap. so this Helper is basically a lightweight union. which means β€” and I cannot stress this enough β€” it comes with a whole list of "LIMITATIONS" (scroll down, we'll get there 🫢).

the thing that makes this module special is that the ResultSet doing the search_or-ing still limits everything correctly. so like, to be super clear, this here only returns $user's friends that match either of the following criteria:

my $friend_rs = $schema->resultset('Friend');
my @internet_friends = $user->friends->search_or([
  $friend_rs->on_facebook,
  $friend_rs->on_twitter,
])->all;

whereas with a union you'd have to do the whole thing like this:

$user->friends->on_facebook->union([ $user->friends->on_twitter ]);

the union works, sure, but it generates more complex SQL which may have lower performance on your database. not the vibe. πŸ™ˆ

oh also β€” go read "NOTE" in DBIx::Class::Helper::ResultSet for a really nice way to apply this to your entire schema. iconic behavior.


πŸŽ€ METHODS πŸŽ€

search_or

my $new_rs = $rs->search_or([ $rs->foo, $rs->bar ]);

search_or takes a single arrayref of ResultSets. that's it. one arrayref.

⚠️ the ResultSets must point to the same source, or you will get an error message. periodt.

also, side note, there is no check made to ensure that more than one ResultSet is in the ArrayRef β€” but honestly bestie, only passing one ResultSet would not make any sense, so like. don't. πŸ’…


πŸ’€ LIMITATIONS πŸ’€

so because this module is basically an expression union and not a true union, "JOIN"s won't Just Workβ„’. if you've got a ResultSet method that uses a "JOIN" and you wanna "OR" it with another method, you'll need to do something like this:

my @authors = $authors->search(undef, { join => 'books' }))->search_or([
   $authors->wrote_good_books,
   $authors->wrote_bestselling_books,
])->all;

also, and this is the important one: if you want to "OR" two methods that "JOIN" in the same relationship via alternate paths, you must use union. no shortcut, sorry queen 😭


πŸ‘‘ AUTHOR πŸ‘‘

Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>


This software is copyright (c) 2024 by Arthur Axel "fREW" Schmidt.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


and that's the whole page bestie 🫢 this was perl v5.40.0, dated 2024-11-16, and it's DBIx::...archOr(3pm) β€” mwah, go write some ORs, you ate πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from