wizardofza
wizardofza

Reputation: 653

cakephp data format inconsitency

I see data returned in different formats for different models and I don't know why.

I have the following 2 models defined (I realize the associations don't make complete sense - I changed their context - but the issue exists :) :

//
// RecipeItem Model
//
class RecipeItem extends AppModel
    public $belongsTo = array(
        'Recipe' => array(
            'className' => 'Recipe',
            'foreignKey' => 'recipe_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'Ingredient' => array(
            'className' => 'Ingredient',
            'foreignKey' => 'ingredient_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
};

//
// Ingredient Model
//
class Ingredient extends AppModel {
    public $belongsTo = array(
        'IngredientType' => array(
            'className' => 'IngredientType',
            'foreignKey' => 'ingredient_type_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'User' => array(
            'className' => 'User',
            'foreignKey' => 'user_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
};

//
// IngredientType
//
class IngredientType extends AppModel {
    public $hasMany = array(
        'Ingredient' => array(
            'className' => 'Ingredient',
            'foreignKey' => 'ingredient_type_id',
            'dependent' => false,
            'conditions' => '',
            'fields' => '',
            'order' => '',
            'limit' => '',
            'offset' => '',
            'exclusive' => '',
            'finderQuery' => '',
            'counterQuery' => ''
        )
    );
};

I get my data returned in this format :

    "RecipeItem": [
        {
            "id": "16181",
            "recipe_id": "4150",
            "ingredient_id": "6866",
            "amount_in_ounces": "16.00",
            "created": "2014-08-06 21:34:50",
            "modified": "2014-08-06 21:34:50",
            "Ingredient": {
                "id": "6866",
                "ingredient_type_id": "2",
                "user_id": "1",
                "name": "Cinnamon",
                "notes": "Cinnamon spice notes",
                "favorite": "0",
                "created": "2014-07-20 23:13:08",
                "modified": "2014-07-20 23:13:08",
                "IngredientType": {
                    "id": "2",
                    "name": "Spice"
                }
            }
        },
    ];

when I use Containable in my Controller :

$data = $this->Recipe->find( 'first',
            array(
                'contain'   => array(
                    'RecipeItem' => array('Ingredient' => array('IngredientType')),
                ),
                'conditions' => array(
                    'Recipe.id' => $this->request['id'],
                    'Recipe.user_id' => $this->request['user_id']
                )
            )
        );

But CakePHP returns the default format at times :

{
    "Ingredient": {
        "id": "6784",
        "ingredient_type_id": "5",
        "user_id": "1",
        "name": "Cinnamon",
        "notes": "Some notes...",
        "favorite": "0",
        "created": "2014-07-20 23:13:08",
        "modified": "2014-07-20 23:13:08"
    },
    "IngredientType": {
        "id": "5",
        "name": "Allspice"
    },
    "User": {
        "id": "1",
        "username": "ccampise",
        "password": "3eccc6ad7b84c40434740c782266ec3cced19133",
        "notes": null,
        "created": "2014-05-16 18:27:56",
        "modified": "0000-00-00 00:00:00"
    }
},
....

at other times when I use the same Containable notation :

$data = $this->Ingredient->find( 'first',
    array(
        'contain'   => array('IngredientType'),
    )
);

I'm not sure I have a preference, but I do prefer to use one or the other, and not both for consistency in my models.

Any thoughts? Thanks!

Upvotes: 1

Views: 60

Answers (2)

Gadget Blaster
Gadget Blaster

Reputation: 761

I was having the same issue. This function will consistently nest data returned by cake's inconsistent contain results.

// model

public function formatData(&$data) 
{
    if (isset($data[0])) {
        foreach ($data as $key => $item) {
            $this->formatData($data[$key]);
        }
    } else {
        $firstKey = key($data);
        $mainData = reset($data);
        unset($data[key($data)]);
        $data = array($firstKey => array_merge($mainData, $data));
    }   
}

// controller

$this->User->formatData($data);

As a side note CakePHP 3 does not seem to suffer from this inadequacy.

Upvotes: 0

nanoman
nanoman

Reputation: 1069

This is CakePHP's default behavior, determining on how to place 1-n relations in the result array based on the model you're querying.

If you really want to change this, you can always hook into the afterFind(), but it will cause more confusion in the future.

I'm afraid you'll have to get used to this.

Upvotes: 0

Related Questions