# Conditional validation on edit of object

**URL:** <https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329>\
**Category:** Need Help\
**Created:** [June 30, 2019, 11:20am UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329 "2019-06-30T11:20:22Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![bankai](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bankai/32/620_2.png) [@bankai](https://discourse.cakephp.org/u/bankai)\
**Post date:** [June 30, 2019, 11:20am UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/1 "2019-06-30T11:20:22Z")

</div>

Hmm.

A bit of context: this is a Trip table which has multiple "price’ columns; only one of them needs to be filled in, depending on the type of the trip, but it must be filled in. So I created conditional validation rules on my model:

```
public function validationDefault (Validator $validator)
{
  $validator->notEmpty ('offered_price', __ ('De prijs moet ingevuld worden'), function ($context)
  {
    return $context['data']['trip_type'] == 'bulk';
   });
   ... similar rules for other trip_types...
}

```

This works perfectly when adding a new trip; but when **editing** an existing object, I see this error in the form:

```
$this->Form->create($trip);
print $this->Form->control('offered_price');

```

The last line results in this notice:

```
[**Notice** (8)] Undefined index: trip_type [**....Model/Table/TripsTable.php** , line **68**]

```

I found [this post in the forums](https://discourse.cakephp.org/t/conditional-validation/1955) which explains that $context[‘data’] is only valid when patchEntity is called. That makes sense, but I’m only building up the form, not processing it. I think FormHelper uses the same rules to mark fields as required, but how to provide the correct data? I’m sure everybody that uses conditional validations has run into this problem, maybe someone has an elegant solution? The ‘answer’ in the post above (“pass it as provider”) does not provide any clues as how to accomplish this.

---

<div class="post-metadata">

**Author:** ![Graziel](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Graziel](https://discourse.cakephp.org/u/Graziel)\
**Post date:** [June 30, 2019, 11:47am UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/2 "2019-06-30T11:47:36Z")

</div>

well you do as in post - give your original data as provider or just give it necessary data to your `patchEntity`

```auto
$data = $this->request->getData() + ['trip_type' => $trip->trip_type];
$this->Trips->patchEntity($trip, $data);

```

---

<div class="post-metadata">

**Author:** ![bankai](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bankai/32/620_2.png) [@bankai](https://discourse.cakephp.org/u/bankai)\
**Post date:** [June 30, 2019, 12:05pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/3 "2019-06-30T12:05:34Z")

</div>

I’m not doing anything with the data, I’m just generating the form (I updated the question to highlight where the error occurs).

---

<div class="post-metadata">

**Author:** ![Graziel](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Graziel](https://discourse.cakephp.org/u/Graziel)\
**Post date:** [June 30, 2019, 12:23pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/4 "2019-06-30T12:23:50Z")

</div>

you are only giving `offered_price` in `$context['data']` so you get error of `Undefined index: trip_type` you need to supply it (trip\_type) somehow, i gave you 2 options to do it

---

<div class="post-metadata">

**Author:** ![bankai](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bankai/32/620_2.png) [@bankai](https://discourse.cakephp.org/u/bankai)\
**Post date:** [June 30, 2019, 3:46pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/5 "2019-06-30T15:46:02Z")

</div>

I understand why I get an Undefined index, just asking if there is an elegant way to prevent it…  
As to the provider, I read the post and the link to Validation class, it just doesn’t make much sense that I have to do things double and at different places (Controller **and** Model). The data is _there_, it is provided to the FormHelper with create() (the $trip object is filled with the existing data), why can’t I use it? Again, I am not validating anything, not processing the form, just **generating** it.

---

<div class="post-metadata">

**Author:** ![Graziel](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Graziel](https://discourse.cakephp.org/u/Graziel)\
**Post date:** [June 30, 2019, 4:05pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/6 "2019-06-30T16:05:10Z")

</div>

maybe something like

[https://book.cakephp.org/3.0/en/orm/validation.html#validating-data-before-building-entities](https://book.cakephp.org/3.0/en/orm/validation.html#validating-data-before-building-entities)

```auto
$article = $articles->newEntity(
    $this->request->getData(),
    ['validate' => false]
);

```

it will skip validation, usefull when you just want entity for your form

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [June 30, 2019, 7:21pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/7 "2019-06-30T19:21:49Z")

</div>

Your validation function should check whether there is data provided, and behave as required for the other scenario when there isn’t.

---

<div class="post-metadata">

**Author:** ![bankai](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bankai/32/620_2.png) [@bankai](https://discourse.cakephp.org/u/bankai)\
**Post date:** [June 30, 2019, 7:46pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/8 "2019-06-30T19:46:13Z")

</div>

Yes, I wrapped the check in an

```
if (!empty($context['data']))
{
 ...
}

```

However, marking it as required makes it impossible to submit the form since there will be a “required” attribute in the \<input\> tag, even the fields that are currently hidden. But not making it non-required is not a problem since the validation will kick in again when submitting the data.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [June 30, 2019, 8:56pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/9 "2019-06-30T20:56:51Z")

</div>

Does adding `} else { return false; }` improve the situation?

---

<div class="post-metadata">

**Author:** ![bankai](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/bankai/32/620_2.png) [@bankai](https://discourse.cakephp.org/u/bankai)\
**Post date:** [July 1, 2019, 8:42pm UTC](https://discourse.cakephp.org/t/conditional-validation-on-edit-of-object/6329/10 "2019-07-01T20:42:27Z")

</div>

Not in all cases; the various allowEmpty\* / notEmpty functions seem to have different opinions on what to return (true or false). In the end I will remove the conditional checks, or replace them with various validation sets that are manually selected when processing the form (there are too many interdependencies).
