in reply to Catalyst: model & context object usage

I just finished the tutorial on CPAN a couple of weeks ago. A join is created shortly after your first code sample.

# Add a record to the join table for this book, mapping to # appropriate author $book->add_to_book_authors({author_id => $author_id}); # Note: Above is a shortcut for this: # $book->create_related('book_authors', {author_id => $author_ +id}); # Assign the Book object to the stash for display in the view $c->stash->{book} = $book;

As for your second question. You need to show me what you have in the list subroutine for me to understand what is going on. Your template file is calling 'books/list' which means 'sub list' in Books.pm (you should have created that in the previous tutorial "More Catalyst Basics' In the tutorial on CPAN it looks like this:

sub list : Local { # Retrieve the usual Perl OO '$self' for this object. $c is th +e Catalyst # 'Context' that's used to 'glue together' the various compone +nts # that make up the application my ($self, $c) = @_; # Retrieve all of the book records as book model objects and s +tore in the # stash where they can be accessed by the TT template $c->stash->{books} = [$c->model('DB::Books')->all]; # Set the TT template to use. You will almost always want to +do this # in your action methods (action methods respond to user input + in # your controllers). $c->stash->{template} = 'books/list.tt2'; }

If you haven't been there yet you can find all the most updated chapters on CPAN here

-Actualize

Replies are listed 'Best First'.
Re^2: Catalyst: model & context object usage
by marscld (Beadle) on Aug 11, 2008 at 05:46 UTC
    Thanks Actualize. Here is the list sub.
    sub list : Local { # Retrieve the usual Perll OO '$self' for this object. $c is the C +atalyst # 'Context' that's used to 'glue together' the various components # that make up the application. my ($self, $c) = @_; # Retrieve all of the book records as book model objects and store + in the # stash where they can be accessed by the TT template $c->stash->{books} = [$c->model('DB::Books')->all]; # Set the TT template to use. You will almost always want to do th +is # in your action methods (action methods respond to user input in # your controllers). $c->stash->{template} = 'books/list.tt2'; }

      Your sub list is exactly the same as it is in the tutorial. After looking over the tutorial and thinking about the error, it looks like the id field for the author is not being passed to the object. There are a few reasons this could happen.

    • It could be because you are typing in the wrong url
    • Here's the right one: http://localhost:3000/books/url_create/TCPIP_Illustrated_Vol-2/5/4
    • It also could be because there is an error in the code I posted above for joining with the author id:
    • # Add a record to the join table for this book, mapping to # appropriate author $book->add_to_book_authors({author_id => $author_id}); # Note: Above is a shortcut for this: # $book->create_related('book_authors', {author_id => $author_id}); # Assign the Book object to the stash for display in the view $c->stash->{book} = $book;
    • It could be some errors in the DBIx::Class setup from "More Catalyst Basics".
    • If you happen to leave out a line or write an error in your schema files, your queries may not come out correctly.

      -Actualize
        Here is the error while accessing url http://localhost:3000/books/url_create/TCPIP_Illustrated_Vol-2/5/4.
        DBI Exception: DBD::Oracle::st execute failed: ORA-01400: cannot inser +t NULL into ("SDB2"."BOOKS"."ID") (DBD ERROR: OCIStmtExecute) [for St +atement "INSERT INTO books (rating, title) VALUES (?, ?)" with ParamV +alues: :p1='5', :p2='TCPIP_Illustrated_Vol-2']
        There is a way to bypass the error, assigning a value to id(Primary Key). Primary key is supposed to be self-increase, right ?
        sub url_create : Local { my ($self, $c, $title, $rating, $author_id) = @_; # Call create() on the book model object. Pass the table # columns/field values we want to set as hash values my $book = $c->model('DB::Books')->create({

        id => '10',

        title => $title, rating => $rating }); }