Search code examples
cakephpcakephp-2.1

CakePHP how to create hasMany data without knowing the foreign key in one saveAll?


I was hoping to create and save the associated data like what I did with belongsTo data - the associated data are created on the fly and foreign ID is also generated and saved on the fly by a single call to saveAll or saveAssocated which has transaction built-in.

But this seems not the case for data in hasMany relationship. Take User and Comment as example. Comment has user_id as the foreign key.

It seems that I cannot save User $data by using single saveAll($data) on User

Array(
    'name' => 'Jack',
    'email' => '[email protected]',
    'Comment' => array(
         array(
            'title' => 'I like this article.'
         )
    )
)

I read some docs. It seems that I need to mention the user_id as the foreign key for the Comment data to create correctly.

If that's the case, since I don't have user ID until it's created, it seems that I need to code to let SAVE happen twice.

I really think that I am missing something. There should be a CAKE way for doing this.


Solution

  • This is done automatically by Cake as long as you follow the conventions and format the data accordingly. For hasMany associations, the main model data, and the associated model data, need to be set on string keys on the same level, like

    array
    (
        'User' => array(),
        'Comment' => array()
    )
    

    Also note that

    The saveAll function is just a wrapper around the saveMany and saveAssociated methods. it will inspect the data and determine what type of save it should perform. If data is formatted in a numerical indexed array, saveMany will be called, otherwise saveAssociated is used.

    This function receives the same options as the former two, and is generally a backwards compatible function. It is recommended using either saveMany or saveAssociated depending on the case.

    So either will do.

    Long story short, the model data needs to be separated and indexed by string keys, it's essentially the same format as a find() call would return it. That way Cake will know that it needs to save associated data, and will automatically insert the foreign key for the Comment records.

    array
    (
        'User' => array
        (
            'name' => 'Jack',
            'email' => '[email protected]'
        ),
        'Comment' => array
        (
            array
            (
                'title' => 'I like this article.'
            )
        )
    )
    

    See also