removing debug statement
[dbsrgits/DBIx-Class-Historic.git] / lib / DBIx / Class / Manual / Cookbook.pod
index 7d0de14..bde68ea 100644 (file)
@@ -237,29 +237,49 @@ any of your aliases using either of these:
 
 =head2 SELECT DISTINCT with multiple columns
 
-  my $rs = $schema->resultset('Foo')->search(
+  my $rs = $schema->resultset('Artist')->search(
     {},
     {
-      select => [
-        { distinct => [ $source->columns ] }
-      ],
-      as => [ $source->columns ] # remember 'as' is not the same as SQL AS :-)
+      columns => [ qw/artist_id name rank/ ],
+      distinct => 1
+    } 
+  );
+
+  my $rs = $schema->resultset('Artist')->search(
+    {},
+    {
+      columns => [ qw/artist_id name rank/ ],
+      group_by => [ qw/artist_id name rank/ ],
     }
   );
 
+  # Equivalent SQL:
+  # SELECT me.artist_id, me.name, me.rank
+  # FROM artist me
+  # GROUP BY artist_id, name, rank
+
 =head2 SELECT COUNT(DISTINCT colname)
 
-  my $rs = $schema->resultset('Foo')->search(
+  my $rs = $schema->resultset('Artist')->search(
     {},
     {
-      select => [
-        { count => { distinct => 'colname' } }
-      ],
-      as => [ 'count' ]
+      columns => [ qw/name/ ],
+      distinct => 1
     }
   );
 
-  my $count = $rs->next->get_column('count');
+  my $rs = $schema->resultset('Artist')->search(
+    {},
+    {
+      columns => [ qw/name/ ],
+      group_by => [ qw/name/ ],
+    }
+  );
+
+  my $count = $rs->count;
+
+  # Equivalent SQL:
+  # SELECT COUNT( * ) FROM (SELECT me.name FROM artist me GROUP BY me.name) count_subq: 
 
 =head2 Grouping results
 
@@ -316,7 +336,7 @@ from, select, and +select attributes.
   my $rs = $cdrs->search({
     year => {
       '=' => $cdrs->search(
-        { artistid => { '=' => \'me.artistid' } },
+        { artist_id => { '=' => \'me.artist_id' } },
         { alias => 'inner' }
       )->get_column('year')->max_rs->as_query,
     },
@@ -329,7 +349,7 @@ That creates the following SQL:
    WHERE year = (
       SELECT MAX(inner.year)
         FROM cd inner
-       WHERE artistid = me.artistid
+       WHERE artist_id = me.artist_id
       )
 
 =head3 EXPERIMENTAL
@@ -409,15 +429,20 @@ C<bind> attributes:
 =head2 Using joins and prefetch
 
 You can use the C<join> attribute to allow searching on, or sorting your
-results by, one or more columns in a related table. To return all CDs matching
-a particular artist name:
+results by, one or more columns in a related table.
+
+This requires that you have defined the L<DBIx::Class::Relationship>. For example :
+
+  My::Schema::CD->has_many( artists => 'My::Schema::Artist', 'artist_id');
+
+To return all CDs matching a particular artist name, you specify the name of the relationship ('artists'):
 
   my $rs = $schema->resultset('CD')->search(
     {
-      'artist.name' => 'Bob Marley'    
+      'artists.name' => 'Bob Marley'    
     },
     {
-      join => 'artist', # join the artist table
+      join => 'artists', # join the artist table
     }
   );
 
@@ -426,16 +451,19 @@ a particular artist name:
   # JOIN artist ON cd.artist = artist.id
   # WHERE artist.name = 'Bob Marley'
 
+In that example both the join, and the condition use the relationship name rather than the table name
+(see DBIx::Class::Manual::Joining for more details on aliasing ).
+
 If required, you can now sort on any column in the related tables by including
-it in your C<order_by> attribute:
+it in your C<order_by> attribute, (again using the aliased relation name rather than table name) :
 
   my $rs = $schema->resultset('CD')->search(
     {
-      'artist.name' => 'Bob Marley'
+      'artists.name' => 'Bob Marley'
     },
     {
-      join     => 'artist',
-      order_by => [qw/ artist.name /]
+      join     => 'artists',
+      order_by => [qw/ artists.name /]
     }
   );
 
@@ -472,12 +500,12 @@ This allows you to fetch results from related tables in advance:
 
   my $rs = $schema->resultset('CD')->search(
     {
-      'artist.name' => 'Bob Marley'
+      'artists.name' => 'Bob Marley'
     },
     {
-      join     => 'artist',
-      order_by => [qw/ artist.name /],
-      prefetch => 'artist' # return artist data too!
+      join     => 'artists',
+      order_by => [qw/ artists.name /],
+      prefetch => 'artists' # return artist data too!
     }
   );
 
@@ -497,9 +525,6 @@ L<DBIx::Class> has now prefetched all matching data from the C<artist> table,
 so no additional SQL statements are executed. You now have a much more
 efficient query.
 
-Note that as of L<DBIx::Class> 0.05999_01, C<prefetch> I<can> be used with
-C<has_many> relationships.
-
 Also note that C<prefetch> should only be used when you know you will
 definitely use data from a related table. Pre-fetching related tables when you
 only need columns from the main table will make performance worse!
@@ -617,7 +642,7 @@ CD and Concert, and join CD to LinerNotes:
 
 =head2 Multi-step prefetch
 
-From 0.04999_05 onwards, C<prefetch> can be nested more than one relationship
+C<prefetch> can be nested more than one relationship
 deep using the same syntax as a multi-step join:
 
   my $rs = $schema->resultset('Tag')->search(
@@ -657,8 +682,7 @@ method.
 
 AKA getting last_insert_id
 
-If you are using PK::Auto (which is a core component as of 0.07), this is 
-straightforward:
+Thanks to the core component PK::Auto, this is straightforward:
 
   my $foo = $rs->create(\%blah);
   # do more stuff
@@ -717,6 +741,48 @@ Just use C<find_or_new> instead, then check C<in_storage>:
     # do whatever else you wanted if it was a new row
   }
 
+=head2 Static sub-classing DBIx::Class result classes 
+
+AKA adding additional relationships/methods/etc. to a model for a
+specific usage of the (shared) model.
+
+B<Schema definition> 
+    package My::App::Schema; 
+     
+    use base DBIx::Class::Schema; 
+
+    # load subclassed classes from My::App::Schema::Result/ResultSet
+    __PACKAGE__->load_namespaces;
+
+    # load classes from shared model
+    load_classes({
+        'My::Shared::Model::Result' => [qw/
+            Foo
+            Bar
+        /]});
+
+    1;
+B<Result-Subclass definition> 
+    package My::App::Schema::Result::Baz;
+     
+    use strict; 
+    use warnings; 
+    use base My::Shared::Model::Result::Baz; 
+    
+    # WARNING: Make sure you call table() again in your subclass,
+    # otherwise DBIx::Class::ResultSourceProxy::Table will not be called
+    # and the class name is not correctly registered as a source
+    __PACKAGE__->table('baz'); 
+     
+    sub additional_method { 
+        return "I'm an additional method only needed by this app"; 
+    }
+
+    1;
+     
 =head2 Dynamic Sub-classing DBIx::Class proxy classes 
 
 AKA multi-class object inflation from one table
@@ -744,7 +810,9 @@ B<Schema Definition>
      
     use base qw/DBIx::Class::Schema/; 
  
-    __PACKAGE__->load_namespaces; 
+    __PACKAGE__->load_namespaces;
+
+    1;
  
  
 B<Proxy-Class definitions> 
@@ -782,7 +850,9 @@ B<Proxy-Class definitions>
         print "I am a regular user.\n"; 
         return ; 
     } 
-     
+    
+    1;
+
      
     package My::Schema::Result::User::Admin; 
      
@@ -800,7 +870,9 @@ B<Proxy-Class definitions>
     { 
         print "I am doing admin stuff\n"; 
         return ; 
-    } 
+    }
+
+    1;
  
 B<Test File> test.pl 
  
@@ -1036,8 +1108,8 @@ declaration, like so...
   
   __PACKAGE__->table('database1.artist'); # will use "database1.artist" in FROM clause
   
-  __PACKAGE__->add_columns(qw/ artistid name /);
-  __PACKAGE__->set_primary_key('artistid');
+  __PACKAGE__->add_columns(qw/ artist_id name /);
+  __PACKAGE__->set_primary_key('artist_id');
   __PACKAGE__->has_many('cds' => 'MyDatabase::Main::Cd');
 
   1;