CakePHP empty Fields of associations are saved instead of discard

1.3k views Asked by At

I have a small project on CakePHP. It has a table named articles, and 5 tables of Fields like categories, tags, images, etc. The associations are mostly HasOne, and associated tables has multiple column. When saving data on articles table everything look good, but on some associations, for example: Article -> Rating, if I did not fill up some fields of Rating tables, that are being saved as null:

+----+------------+--------------+
| id | article_id | rating_value |
+----+------------+--------------+
|  1 |         36 |            3 |
|  2 |         56 |      5454.56 |
|  3 |         57 |            4 |
|  5 |         51 |         NULL |
+----+------------+--------------+

If I add some validations, then I can't save the article as it need to be validated. All I want is that if rating_value is empty, then it must not be created as null (entity rejected), and the article must be saved. Deleting articles works as expected, all related entities are deleted.

I tried altering $data on Model.beforeMarshall but the class is private in both Tables Articles and Ratings (i think associations may be the problem).

Some code (controller add):

public function add()
    {
    $article = $this->Articles->newEntity();
    if ($this->request->is('post')) {
                $article = $this->Articles->patchEntity($article, $this->request->data, [
                    'associated' => [
                        'Ratings',
                    ]
                ]);
                if ($this->Articles->save($article)) {
                    $this->Flash->success(__('Saved.'));
                    return $this->redirect(['action' => 'index']);
                }
    }
    $this->set('article', $article);
}

I deleted all validations of every associated Model because of this.

// Articles Table
$this->hasOne('Ratings', [
    'className' => 'Ratings',
    'dependent' => true,
]);

// Ratings Table
$this->belongsTo('Articles', [
    'foreignKey' => 'article_id',
    'joinType' => 'INNER'
]);
// Rating.php Entity
protected $_accessible = [
    '*' => true,
    'id' => false
];
// Article.php Entity
protected $_accessible = [
    '*' => true,
];
2

There are 2 answers

1
Aman Rawat On

If you are setting rating_value then it will try to save and validate with all validation rules.

You can remove the associated data if rating_value is empty like this

$dataToSave = $this->request->data;
if(empty($dataToSave['rating']['rating_value'])){
    unset($dataToSave['rating']);
}
$article = $this->Articles->patchEntity($article, $dataToSave, [
    'associated' => [
        'Ratings',
    ]
]);
2
Manohar Khadka On

I thing every thing looks good.May be your field in table has default value as null. For example:

If 'rating_value' field in your table has default value null,
make that default full to none first.

If validation fails that don't give you save anything rather than saving null value.If that still don't work for you see:

debug($this->request->data);

And look there if data are coming correctly from your view(form). Another important thing is that you can use different validation set for association. (see here)