# Adding new entity through foreign controller with custom form input names

**URL:** <https://discourse.cakephp.org/t/adding-new-entity-through-foreign-controller-with-custom-form-input-names/7822>\
**Category:** Uncategorized\
**Created:** [May 15, 2020, 1:05pm UTC](https://discourse.cakephp.org/t/adding-new-entity-through-foreign-controller-with-custom-form-input-names/7822 "2020-05-15T13:05:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [May 15, 2020, 1:05pm UTC](https://discourse.cakephp.org/t/adding-new-entity-through-foreign-controller-with-custom-form-input-names/7822/1 "2020-05-15T13:05:34Z")

</div>

I set up XController-\>add() to create a new entity for Products.  
public function add()  
{   
$this-\>loadModel(‘Products’);  
…  
$newProduct= $this-\>Products-\>newEmptyEntity();  
$product\_form\_input=[‘product\_name’,‘product\_size’,‘product\_brand’,‘product\_category\_id’];  
$product\_fields = array\_intersect\_key($this-\>request-\>getData(), array\_flip($product\_form\_input));

$newProduct = $this-\>Products-\>patchEntity($newProduct, $product\_fields);

if ($this-\>Products-\>save($newProduct)) {  
$this-\>Flash-\>success(\_\_(‘The new Product has been saved.’));  
…}

However, I can’t find in the documentation how to match the required input of patchEntity to make the save successful. In ProductsTable.php I used the product\_ prefix in the validator, although this was my best clue rather than understanding:

```
e.g. $validator
        ->scalar('product_name')
        ->maxLength('product_name', 64)
        ->requirePresence('product_name', 'create')
        ->notEmptyString('product_name'); 

```

Debugging indicates that this does lead to correct validations, although no new product is added to the DB (PhpMyAdmin).  
I assume I have to explicitly match the table names without the product-prefix, to the ones with the prefix coming from the form. I don’t want to use the field names without the prefix, since I would like to use the same form for name fields of several models (such that getData contains both X\_name as Y\_name etc.)  
For confirmation: the product\_ fields are form inputs from the add() template of X.

Moreover, I want to let the DB create the id (which is done by `->allowEmptyString('id', null, 'create')`) , but access this immediately after saving such that it can be given to a new entity of X. Is this possible?

---

<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:** [May 15, 2020, 3:26pm UTC](https://discourse.cakephp.org/t/adding-new-entity-through-foreign-controller-with-custom-form-input-names/7822/2 "2020-05-15T15:26:01Z")

</div>

It’s not entirely clear here what you’re trying to do. You want to have fields in the form with different names than they do in the database? So your form has controls named `product_name`, `product_size`, etc., but your Products table has just `name`, `size`, etc.? What you provide to `patchEntity` (and the names of the fields you validate on) must exactly match the table, so if there’s some mapping to be done then you need to do that yourself. Looks like you’re maybe trying to do that with the `array_intersect_key` call? Does the resulting `$product_fields` have the keys you expect to see?

Anyway, if you proceed with this, the next issue you’re going to have is that any validation errors won’t show up in your form, because the field names in the entity won’t match the form any more.

This overall seems like a case of overly aggressive optimization. Lots of times that I’ve seen symmetries between things which don’t really pan out and just end up making everything more complicated. Code should be DRY, but not _too_ dry; just like many things in the real world, if it gets too dry, it gets brittle and is likely to break. 🙂

If you really need to do this, I’d suggest that you move the “prefix” handling to the _template_ instead of the controller, e.g. `$this->Html->control("{$prefix}name")`, where `$prefix` may be `product_` or it might be blank, depending on who is calling it.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [May 15, 2020, 5:50pm UTC](https://discourse.cakephp.org/t/adding-new-entity-through-foreign-controller-with-custom-form-input-names/7822/3 "2020-05-15T17:50:00Z")

</div>

> [@Zuluru](#):
>
> So your form has controls named `product_name` , `product_size` , etc., but your Products table has just `name` , `size` , etc.?

Correct. For the exact reason you are confirming.

> [@Zuluru](#):
>
> What you provide to `patchEntity` (and the names of the fields you validate on) must exactly match the table, so if there’s some mapping to be done then you need to do that yourself.

That’s clear then, thanks.

> [@Zuluru](#):
>
> Looks like you’re maybe trying to do that with the `array_intersect_key` call? Does the resulting `$product_fields` have the keys you expect to see?

No, with this I extract only the relevant fields of getData(). Since getData(‘x’, ‘y’, ‘z’) retrieves only the first argument. But this may be superfluous if the patchEntity automatically addresses the right fields, that I don’t know and is partly the reason for issuing this topic. I assumed the complete getData() as input would be troublesome as it contains form data of multiple models.

> [@Zuluru](#):
>
> If you really need to do this,

Well, I am unsure. I am quite sure it is not, respecting your experience and indication of doubt.  
This is just another attempt to enable one user-facing form to possibly create entities of different models. This is one way of trying next to [Nested add forms of multiple tables via form buttons - #12 by Zuluru](https://discourse.cakephp.org/t/nested-add-forms-of-multiple-tables-via-form-buttons/7806/12). I figured multiple models need to be handled in one controller function/method, one way or another.

---

<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:** [May 15, 2020, 6:20pm UTC](https://discourse.cakephp.org/t/adding-new-entity-through-foreign-controller-with-custom-form-input-names/7822/4 "2020-05-15T18:20:02Z")

</div>

`patchEntity` is going to take whatever values are in the provided data and set them under the exact same keys in the entity (assuming that the `accessible` setting allows it). So, if you give it an array with a `product_name` key in it, that value is going to be in the `product_name` property of the entity. If there’s no field called that in the database, then it’s not going to be saved anywhere. You need to make sure that what you’re giving it has a key just called `name` if that’s what the database is expecting.

You can do that with fancy coding in the controller (accounting for both the incoming data format and the required difference in validation errors), or you could do that same stuff in places like `beforeMarshal`, or you can just save yourself the headaches and have a different form for this particular model. There’s a famous saying: “Premature optimization is the root of all evil.” How you’re trying to do it feels like premature optimization to me.
