Monday, February 28, 2011

Re: Can't Save to DB

Ryan:
Per the CakePHP Book, saveAll() has two variations (http://
book.cakephp.org/view/1031/Saving-Your-Data):

"For saving multiple records of single model, $data needs to be a
numerically indexed array of records like this:"

and

"For saving a record along with its related record having a hasOne or
belongsTo association, the data array should be like this:"

so theweirdone's latest changes in message #5 seems appropriate for
what he's describing. And the function desription for create() is also
on the same page, preceded with an info box indicating:

"When calling save in a loop, don't forget to call create()."

theweirdone:
If you don't already have debug set to development mode (i.e.
Configure::write('debug', 2); ), do so while you are still writing the
code (change this to zero when you deploy to production, though).
With debug set to > 0, the SQL statements that are being issued
against the database should be listed below the "normal" rendered
page. If it's not listing any INSERTs into your episodes table, it
could very well be that the data is failing your model validation.
For example, are you using the 'date' core validation rule on the
'date' column (default format is 'ymd', and your sample data is
'mdy')?

Slightly off-topic: your code includes the following lines:
$show = $this->requestAction('/shows/getTvById/'.$id); //gets the
tv.com url
$episodes = $this->scrape($show, $id); //scrapes tv.com for the
show

I am assuming that Show hasMany Episode and Episode belongsTo Show and
that the column name containing the tv.com url is 'url'. If so, you
might want to consider the following instead:
$show = $this->Episode->Show->findById($id, array('id', 'url')); //
gets the tv.com url
$episodes = $this->scrape($show); // scrapes tv.com for the show

By using the requestAction() method, CakePHP has to go through the
Router (to determine which plugin/controller/action needs to be
called), then Dispatcher (to set up the controller and model(s)/
component(s)/etc), then the ShowController to run the getTvById()
action, which ultimately will execute some variant of $this->Show-
>find(). That's a lot of overhead that you can bypass by executing
the find() directly on the Show model (related to the Episode model
which is already loaded by the current controller, hence accessible as
$this->Episode->Show). And if the return value contains both the id
and url, your scrape method would only need one parameter instead of
two.


On Feb 28, 12:48 pm, Ryan Schmidt <google-2...@ryandesign.com> wrote:
> On Feb 28, 2011, at 14:23, theweirdone wrote:
>
>
>
>
>
> > I've changed my code, here's the new controller:
>
> > function addAll($id = null) {
> >         if (!$id) {
> >             $this->Session->setFlash(__('Invalid show id entered', true));
> >             //$this->redirect('/episodes');
> >         }
> >         $show = $this->requestAction('/shows/getTvById/'.$id); //gets the tv.com url
> >         $episodes = $this->scrape($show, $id); //scrapes tv.com for the show
> >         $this->set('episodes', $episodes); //sets $TVshowInfo for the view
> >         if($this->Episode->saveAll($episodes['Episode'])){
> >             $this->Session->setFlash(__($count.' episodes were saved.', true));
> >         }
> >     }
>
> > I've also updated the scraper to return the array such as in the manual:
>
> > Array
> > (
> >     [Episode] => Array
> >         (
> >             [0] => Array
> >                 (
> >                     [name] => Stowaway
> >                     [number] => 17
> >                     [description] => No synopsis available. Write a synopsis.
> >                     [date] => 3/18/2011
> >                     [show_id] => 11
> >                 )
>
> >             [1] => Array
> >                 (
> >                     [name] => Os
> >                     [number] => 16
> >                     [description] => While Walter attempts to figure out a way to stop the spread of vortexes on This Side, the team investigate a series of thefts committed by criminals who can control gravity.
> >                     [date] => 3/11/2011
> >                     [show_id] => 11
> >                 )
> > )
>
> > So now the saveAll() function should be working I think. Yet it still doesn't save anything to the database.
> > Should I put in a for loop and save each episode individually using the save() function? Is there any reason that would be more likely to work?
>
> Well.... saveAll() is described as being for saving one main record and multiple related records. Here, you're trying to save multiple unrelated records. I don't know if saveAll() is meant to work in that case, so maybe a for loop is the way for now after all. I hate recommending that, because I know a single multi-record SQL INSERT statement is more efficient than multiple single-record INSERTs, but I don't know how to do it in CakePHP. Then again, your previous code checked the validity of each save and counted up the number of successful saves, implying you expected some of them not to be successful; a single multi-record INSERT would either completely succeed or completely fail, so that may not be what you want anyway.

--
Our newest site for the community: CakePHP Video Tutorials http://tv.cakephp.org
Check out the new CakePHP Questions site http://ask.cakephp.org and help others with their CakePHP related questions.


To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php

No comments: