I have done quite a bit of reading on the subject of multiple models,
one controller, and one form; but I'm still stumped with a particular
issue I'm trying to solve.

Let me show the code first, I'll explain the problem after the code.
I have the following setup (highly simplified for ease of reading):

A Widget Controller:
-----------------------------------------------
[widgets_controller.php]
<?php
class WidgetsController extends AppController
{
  var $name = 'Widgets';
  var $helpers = array('html');
  var $uses=array('Widget', 'WidgetName', 'WidgetType');


  function addNewWidget()
  {
    if (!empty($this->data))
    {
        if ($this->Widget->save($this->data))
            {
                /* I feel like this is just a hack -- there must be a
better way! */
                $this->data['WidgetName']['widget_id'] = $this->Widget-
>getLastInsertID();
                $this->data['WidgetType']['widget_id'] = $this->Widget-
>getLastInsertID();

                /* Again... I feel like there has to be a better way!
*/
                if ($this->WidgetName->save($this->data)) {
                         if ($this->WidgetType->save($this->data)) {
                                 $this->flash('This entry has been saved.','/
widgets');
                         } else {
                                 //display "widget type error"
messages, et cetera
                         }
                } else {
                       //display "widget name" error messages, et
cetera
                }
            } else {
                //display "widget" error messages, et cetera
            }
    }
  }


}
?>
-----------------------------------------------

Models:
-----------------------------------------------
[widget.php]
<?php
class Widget extends AppModel
{
    var $name = 'Widget';

    var $validate = array(
        'price' => VALID_NOT_EMPTY,

    var $hasOne = array('WidgetName' =>
                        array('className'    => 'WidgetName',
                              'conditions'   => '',
                              'order'        => '',
                              'dependent'    =>  true,
                              'foreignKey'   => ''
                                  ),

                        'WidgetDate' =>
                        array('className'    => 'WidgetDate',
                              'conditions'   => '',
                              'order'        => '',
                              'dependent'    =>  true,
                              'foreignKey'   => ''
                                  ),
                        );
}
?>

**************************
[widget_name.php]
<?php
class WidgetName extends AppModel
{
    var $name = 'WidgetName';

    var $belongsTo = array('Widget' =>
                           array('className'  => 'Widget',
                                 'conditions' => '',
                                 'order'      => '',
                                 'foreignKey' => ''
                           )
                     );

}
?>

**************************
[widget_type.php]
<?php
class WidgetType extends AppModel
{
    var $name = 'WidgetType';

    var $belongsTo = array('Widget' =>
                           array('className'  => 'Widget',
                                 'conditions' => '',
                                 'order'      => '',
                                 'foreignKey' => ''
                           )
                     );

}
?>

-----------------------------------------------

View:
-----------------------------------------------
[addNewWidget.thtml]
<h1>Add New Widget</h1>
<form method="post" action="<?php echo $html->url('/widgets/
addNewWidget') ?>">
    <p id="formSpace">
        Widget Price:
        <?php echo $html->input('Widget/price', array('size' => '40'))?
>
        <?php echo $html->tagErrorMsg('Widget/price', 'A widget price
is required.') ?>
    </p>
    <p id="formSpace">
        Widget Name:
        <?php echo $html->input('WidgetName/widget_name', array('size'
=> '40'))?>
        <?php echo $html->tagErrorMsg('WidgetName/widget_name', 'A
widget name is required.') ?>
    </p>
    <p id="formSpace">
        Widget Type:
        <?php echo $html->input('WidgetType/widget_type', array('size'
=> '40'))?>
        <?php echo $html->tagErrorMsg('WidgetType/widget_type', 'A
widget type is required.') ?>
    </p>
 </form>
-----------------------------------------------

The database looks like this (very simplified for this example):
[widgets table]
- id (set to 'auto_increment' in the DB)
- modified (set to 'ON UPDATE CURRENT_TIMESTAMP' in the DB)
- price (INT)

[widget_names table]
- widget_id (with a foreign key of widgets.id)
- widget_name (VARCHAR)

[widget_types table]
- widget_id (with a foreign key of widgets.id)
- widget_type (VARCHAR)
-----------------------------------------------


Questions:

1) I know there must be a more elegant solution to saving the data
from the different models than the method currently shown above in my
controller (specifically the methods to save the data to the different
models).  Please suggest some alternate options.

Specifically, I'm hoping for some sort of magic 'saveModels' kind of
thing that will save to all the models at once without needing to get
the id from the first save and then manually save the rest of the
models in some sort of specific order.  Is there an automatic way to
do this?  Perhaps I have missed something in the API?


2) How do I tackle the validation problem?  Right now, the only
validation that seems to work is the validation for the Widget model
(it's the only one that will return an error to the view).  How do I
validate for each model seperately?

There are more complex problems going on though:

For instance, assume we save an entered price using the Widget model
and return the new id.  Now we take that id and attempt to save the
widget name using the WidgetName model.  If the user failed to enter a
widget name, the validation occurs after a new id is generated.  That
means we have a widget in the widgets table without any corresponding
data in the widget_names & widget_types tables.

How do I deal with this 'cascading validation' problem?  I know it
must be something simple, but everything I try doesn't seem to solve
the problem.  The problem seems to revolve around question 1.


3) What are the rules around the hasOne and belongsTo associations.
In this case, I will only be querying the data from the "Widget"
perspective.  Does that mean I only need to have the hasOne
association and I can skip the belongsTo associations in the
WidgetName & WidgetType models?  I'm wondering if the belongsTo
association is just a waste in this case.


* I think the root of the problem revolves around the three 'save'
methods in the Widgets Controller.  That should be the focus for
anyone trying to understand my problem.

******
I really appreciate any help on these issues in advance.  I will
create a tutorial on my blog regarding what I learn about this stuff
in hopes to stave off any confusion regarding this topic in the
future.
******

- Dustin Weber
http://www.dustinweber.com


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Cake 
PHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/cake-php?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to