[Dbix-class] Confused by search_related

John Napiorkowski jjn1056 at yahoo.com
Sat Oct 6 15:57:08 GMT 2007


--- Paul Makepeace <paulm at paulm.com> wrote:

> In the docs
>
http://search.cpan.org/~ash/DBIx-Class-0.08007/lib/DBIx/Class/Relationship.pm
> there's an example of search_related doing a "select
> *" which I think
> is misleading as it's actually only selecting from
> the related
> resultset not the base(?) resultset, at least in my
> experiments.
> 
> I have SavedView with,
> 
> __PACKAGE__->belongs_to('web_chart_spec' =>
> 'IDL::Schema::WebChartSpec' =>
> 'web_chart_spec_uid');
> 
> My controller does,
> 
>   my @saved_views :Stashed =
>
$c->model('DBIC_Readonly')->resultset('SavedView')->search_related(
> 		'web_chart_spec' => {service_profile_uid =>
> $chart->{service_profile_uid}});
> 
> I get results but nothing from SavedView, just
> WebChartSpec! Debugging
> the SQL reveals it's only selecting on
> web_chart_spec.*. I dunno, if I
> called "resultset('SavedView')" I'm expecting stuff
> with SavedView in
> it.

When you do a search_related you get a new resultset
from the related result_source (in this case it's
WebChartSpec, which is the resultset you specify in
the relationship).  It should also 'limit' the related
resultset by any conditions you've already done. so
for example:

$schema->resultset('rs1')->related_resultset('rs2');

should return a resultset of rs2 where all rs
'belong_to' rs1 (assuming a definition similar to the
one you described).

On the other hand:

$schema
  ->resultset('rs1')
  ->search({value=>$search})
  ->related_resultset('rs2');

returns a resultset of rs2 that belong to rs1 and
where 'value=$search' in rs1.

Remember the SQL doesn't actually get run until you
want some values, so you can continue to add
conditions until you get the exact query you need.

> 
> How can I achieve what I'm intending here? In
> essence,
> 
> select sv.* from saved_view sv
> join web_chart_spec ws on ws.uid =
> sv.web_chart_spec_uid
> where ws.service_profile_uid = ?;
> 
>   my @saved_views :Stashed =
>
$c->model('DBIC_Readonly')->resultset('SavedView')->search(
> 		{'web_chart_spec.service_profile_uid' =>
> $chart->{service_profile_uid}},
> 		{join => ['web_chart_spec']});
> 
> Works but maybe there's a nicer way.
> 
> P

This is correct, if you want to limit a resultset via
it's relations, you need to join those relations.

The only cleaning thing I can think of is to make this
into a custom resultset class method so that you can
just do:

my $rs = $c->model('DBIC::SavedView')->custom_rs;

In your controller.  

There's examples of making a custom resultset in the
cookbook and also there is a new feature that makes it
simple to add custom resultsets.  See: 

http://search.cpan.org/~ash/DBIx-Class-0.08007/lib/DBIx/Class/Schema.pm#load_namespaces

for some of this.  With this plus the ability to set a
custom result_class in your resultset methods, it
makes it much easier to link your physical model (AKA
the result_sources) to true domain logic.

Just stay away from the 'ResultSetManager' component,
which has been superceded by the above methods.

--John

> 
> _______________________________________________
> List:
>
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
> IRC: irc.perl.org#dbix-class
> SVN:
> http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
> Searchable Archive:
>
http://www.grokbase.com/group/dbix-class@lists.rawmode.org
> 



      ____________________________________________________________________________________
Catch up on fall's hot new shows on Yahoo! TV. Watch previews, get listings, and more!
http://tv.yahoo.com/collections/3658 



More information about the DBIx-Class mailing list