Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

Creating & Updating related records

Hi guys,

I have created a controller that saves or updates Product along with its stock and attributes. Each product has one stock level and multiple attributes. I am trying to save everything by just saving $product, like in the documentation. However, if I modify my code like in the example below, no related records are created:

// Create an artist
$artist          = new Artists();
$artist->name    = 'Shinichi Osawa';
$artist->country = 'Japan';

// Create an album
$album         = new Albums();
$album->name   = 'The One';
$album->artist = $artist; // Assign the artist
$album->year   = 2008;

$album->save();

The only way to create/update my related records is by saving the main record (products) and then using the id to save the related records in separate transactions. Here is part of my Products model:

$this->hasMany('id', __NAMESPACE__ . '\ProductAttributes', 'product_id', array(
        'alias' => 'ProductAttributes',
        'foreignKey' => array(
            'action' => Relation::ACTION_CASCADE
        )
    ));

    $this->hasOne('id', __NAMESPACE__ . '\ProductStock', 'product_id', array(
        'alias' => 'ProductStock',
        'foreignKey' => array(
            'action' => Relation::ACTION_CASCADE
        )
    ));

And here are parts of my stock and attributes models:

$this->belongsTo('product_id', _NAMESPACE_ . '\Products', 'id', array(
    'alias' => 'Products'
));

$this->belongsTo('product_id', _NAMESPACE_ . '\Products', 'id', array(
    'alias' => 'Products'
));

It does not really bother me to save related records separately, but I would like to know what I am missing here...

Thanks!



8.1k
Accepted
answer

Hi,

as doc says, you just have to create an instance of your related model (ProductAttributes) then assign it to the product, using defined alias as property name So, in your case :

        $product = new Product();
        //assign values to products
        //...
        $ProductAttributes = new ProductAttributes();
        //assign values to productAttributes
        //..

        $product->ProductAttributes = $ProductAttributes;  //$model->relationAlias = $relatedModel
        $product->save();

...sound like I cloned documentation.. :-/

I think you don't need to define an alias for the belongTo relationship (maybe this is causing trouble in your code), at least, I don't see where you will later use this alias in your code...but maybe I'm wrong.

OK, looks like I was trying it the other way around, using $ProductAttributes->product = $product ...

So, how do I populate a field with array notation using the values? This does not seem to work:

    $this->tag->setDefault("attribute_name", $product->ProductAttributes->attr_name);

here I think $product->ProductAttributes is a resultset containing more than one ProductAttributes (it's a hasMany relation), so try to loop thru $product->ProductAttributes. to use array notation, You can do something like $pAtributes = $product->ProductAttributes->toArray(); then use foreach loop on $pAtributes

edited Jul '16

That was my original thought as well, but for some reason

    foreach( $product->ProductAttributes->toArray() as $attribute ) {
        $this->tag->setDefault("attribute_name", $attribute['attr_name']);
        $this->tag->setDefault("attribute_value", $attribute['attr_value']);
    }

does not populate the field

try to var_dump() your $product->ProductAttributes->toArray(), I use exactly the way you've done with success..