marscld has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, While practising with Catalyst-BasicCRUD.pod, two problems occurred. First, Insert record into Oracle table failed.Error says that 'id' field in table Books should not be null. As code says, it processes Title & Rating field, without Id field. So confused about this, and where to find illustration on method, $c->model('xx')->create().
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({ title => $title, rating => $rating }); ...... }
Second, for TT file to display success action, there is a hyper link of 'Return to list'. However, empty data is filled for alink.
[% # Provide a link back to the list page + -%] [% # 'uri_for()' builds a full URI; e.g., 'http://localhost:3000/b +ooks/list' -%] <p><a href="[% c.uri_for('/books/list') %]">Return to list</a></p>
Could anyone please provide some idea ? Thank you.

Replies are listed 'Best First'.
Re: Catalyst: model & context object usage
by actualize (Monk) on Aug 11, 2008 at 04:48 UTC

    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
      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
Re: Catalyst: model & context object usage
by juster (Friar) on Aug 11, 2008 at 06:28 UTC

    I am a Catalyst newbie as well but it seems to me you might not have the database or DBIC schema setup right. I would make sure you have the primary keys properly defined in the tables and that Schema/ files were created (assuming you are using the static schema by now like in the tutorial).

    DBIC should increment the primary key for you automatically and you don't need to supply it in create. To find documentation on create() look at ResultSet in DBIx::Class. The $c->model('...') objects inherit from DBIx::Class.

    I seem to remember uri_for screwing up on me the same way but I never found out why.

    But start at the database, use DBIC_TRACE=1 script/myapp_server.pl or temporarily switch to SQLite like in the tutorial?

Re: Catalyst: model & context object usage
by maletin (Sexton) on Dec 21, 2008 at 18:53 UTC
    Oracle (and PostgreSQL) don't use an autoincrement in the example. You will need a sequence/trigger/serial to insert rows without a specified value for the primary key.