I need help for my timesheets app model …
What I want to do is an app that allows you to save your times for every day.
I built this model :
Note : I added the hasMany relation from timesheets to timesheets_tasks model because I didn’t manage to access days table by another way
At the end I am not sure the belongsToMany from timesheets to tasks is really appropriate in this situation …
I have 2 questions :
Does this model sound good to you ?
How to save days ?
Because when I save this :
object(App\Model\Entity\Timesheet) {
'id' => (int) 2,
'user_id' => (int) 1,
'week_nb' => (int) 16,
'year' => (int) 2018,
'validated' => false,
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-02T09:25:29+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-28T22:17:29+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'tasks' => [
(int) 0 => object(App\Model\Entity\Task) {
'id' => (int) 1,
'name' => 'Atelier 1 - Compta',
'scope' => 'global',
'user_id' => null,
'project_id' => (int) 1,
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-01T15:19:44+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-01T15:19:44+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Tasks'
},
(int) 1 => object(App\Model\Entity\Task) {
'id' => (int) 2,
'name' => 'Atelier 2 - Achats',
'scope' => 'global',
'user_id' => null,
'project_id' => (int) 1,
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-01T15:20:13+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-01T15:20:13+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Tasks'
}
],
'timesheets_tasks' => [
(int) 0 => object(App\Model\Entity\TimesheetsTask) {
'id' => (int) 13,
'timesheet_id' => (int) 2,
'task_id' => (int) 1,
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-28T22:04:45+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-28T22:04:45+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'days' => [
(int) 0 => object(App\Model\Entity\Day) {
'date' => object(DateTime) {
date => '2018-04-16 22:17:40.643236'
timezone_type => (int) 3
timezone => 'UTC'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
},
(int) 1 => object(App\Model\Entity\Day) {
'date' => object(DateTime) {
date => '2018-04-17 22:17:40.647586'
timezone_type => (int) 3
timezone => 'UTC'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
},
(int) 2 => object(App\Model\Entity\Day) {
'date' => object(DateTime) {
date => '2018-04-18 22:17:40.647655'
timezone_type => (int) 3
timezone => 'UTC'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
},
(int) 3 => object(App\Model\Entity\Day) {
'date' => object(DateTime) {
date => '2018-04-19 22:17:40.647705'
timezone_type => (int) 3
timezone => 'UTC'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
},
(int) 4 => object(App\Model\Entity\Day) {
'date' => object(DateTime) {
date => '2018-04-20 22:17:40.647754'
timezone_type => (int) 3
timezone => 'UTC'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
},
(int) 5 => object(App\Model\Entity\Day) {
'date' => object(DateTime) {
date => '2018-04-21 22:17:40.647796'
timezone_type => (int) 3
timezone => 'UTC'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
},
(int) 6 => object(App\Model\Entity\Day) {
'date' => object(DateTime) {
date => '2018-04-22 22:17:40.647838'
timezone_type => (int) 3
timezone => 'UTC'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
}
],
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'days' => true
],
'[original]' => [
'days' => []
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'TimesheetsTasks'
}
],
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'tasks' => true
],
'[original]' => [
'tasks' => [
(int) 0 => object(App\Model\Entity\Task) {
'id' => (int) 1,
'name' => 'Atelier 1 - Compta',
'scope' => 'global',
'user_id' => null,
'project_id' => (int) 1,
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-01T15:19:44+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-01T15:19:44+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'_joinData' => object(App\Model\Entity\TimesheetsTask) {
'id' => (int) 13,
'timesheet_id' => (int) 2,
'task_id' => (int) 1,
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-28T22:04:45+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-04-28T22:04:45+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'TimesheetsTasks'
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Tasks'
}
]
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Timesheets'
}
I doesn’t save days … The controller :
public function add()
{
$timesheet = $this->Timesheets->newEntity();
if ($this->request->is(['patch', 'post', 'put'])) {
if(!is_null($this->request->getData('id'))) {
$timesheet = $this->Timesheets->get($this->request->getData('id'), ['contain' => ['TimesheetsTasks' => ['Days'], 'Tasks']]);
}
// Here I "create" 7 days entities if a new timesheet_task has been added
$this->initEmptyTasks($timesheet);
$timesheet = $this->Timesheets->patchEntity($timesheet, $this->request->getData(), ['associated' => ['TimesheetsTasks' => ['associated' => ['Days']], 'Tasks']]);
if ($result = $this->Timesheets->save($timesheet)) {
$this->Flash->success(__('The timesheet has been saved.'));
return $this->redirect($this->referer());
}
$this->Flash->error(__('The timesheet could not be saved. Please, try again.'));
return $this->redirect($this->referer());
}
$users = $this->Timesheets->Users->find('list', ['limit' => 200]);
$this->set(compact('timesheet', 'users'));
}
I don’t have any error, but days are not saved …
Thanks in advance for your help.
Oh my god I found the root cause …
I was modifying the entity instead of the data I was patching the entity with …
But now I have one question :
Can you have a BTM pivot table to have hasMany relation with another Table ?
Because I can save _joinData for additionnal field (comment field here), but not for hasMany relation (days table)
Here’s my $data before I call the patchEntity method :
[
'id' => '2',
'week_nb' => '16',
'year' => '2018',
'tasks' => [
(int) 0 => [
'id' => (int) 1,
'_joinData' => [
'comment' => 'Hihi tache 1 new',
'days' => [
(int) 0 => [
'timesheet_task_id' => (int) 35,
'ts_date' => object(DateTime) {
date => '2018-04-16 19:04:45.150726'
timezone_type => (int) 3
timezone => 'Europe/Paris'
}
]
]
]
],
(int) 1 => [
'id' => (int) 2,
'_joinData' => [
'comment' => 'Hihi tache 2'
]
]
]
]
Here’s my data after I call the patchEntity method :
$timesheet = $this->Timesheets->patchEntity($timesheet, $data, ['associated' => ['Tasks._joinData.Days']]);
The _joinData part :
'_joinData' => object(App\Model\Entity\TimesheetsTask) {
'id' => (int) 35,
'timesheet_id' => (int) 2,
'task_id' => (int) 1,
'comment' => 'Hihi tache 1 new',
'created' => object(Cake\I18n\FrozenTime) {
'time' => '2018-05-01T18:39:17+02:00',
'timezone' => 'Europe/Paris',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\FrozenTime) {
'time' => '2018-05-01T18:58:55+02:00',
'timezone' => 'Europe/Paris',
'fixedNowTime' => false
},
'days' => [
(int) 0 => object(App\Model\Entity\Day) {
'timesheet_task_id' => (int) 35,
'ts_date' => object(DateTime) {
date => '2018-04-16 19:02:01.023189'
timezone_type => (int) 3
timezone => 'Europe/Paris'
},
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'timesheet_task_id' => true,
'ts_date' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Days'
}
],
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'days' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'TimesheetsTasks'
},
It seems to be working as cakePHPis converting my day record to a day entity, but same result now, it’s not saving.
Related
I would like to save data this way: 'Orders'->'OrdersFoods'->'OrdersFoodsChanges'. Where OrdersFoodsTable is a join table (Orders - Foods).
Why do I want to do so? Table OrdersFoods contains information about ordered foods (ids), but I would like to save additional data about every ingredient used for that food in particular order. That's why I've created additional table (OrdersFoodsChanges) with id from table OrdersFoods.
I can save data to a joined table but not to another table (OrdersFoodsChangesTable).
I've tried to do it the simplest way:
$order = $this->Orders->patchEntity($order, $this->request->data, [
'associated' => [
'Foods._joinData.OrdersFoodsChanges'
//'Foods.OrdersFoods.OrdersFoodsChanges'
]
but with no luck.
patchEntity object
object(Admin\Model\Entity\Order) {
'user_id' => (int) 1,
'city' => '',
'postal_code' => '',
'street' => '',
'house' => '',
'phone' => '',
'foods' => [
(int) 0 => object(Admin\Model\Entity\Food) {
'id' => (int) 15,
'name' => 'Royal',
'price' => (float) 15,
'category_id' => (int) 2,
'photo_id' => (int) 69,
'shop_id' => (int) 1,
'favorite' => false,
'vat' => (int) 23,
'visible' => true,
'position' => (int) 0,
'_joinData' => object(Admin\Model\Entity\OrdersFood) {
'quantity' => (int) 1,
'orders_foods_changes' => [
(int) 0 => object(Admin\Model\Entity\OrdersFoodsChange) {
'component_quantity' => (int) 25,
'component_id' => (int) 1,
'order_food_id' => (int) 1,
'type' => 'ADD',
'element_num' => (int) 1,
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'component_quantity' => true,
'component_id' => true,
'order_food_id' => true,
'type' => true,
'element_num' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Admin.OrdersFoodsChanges'
}
],
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'quantity' => true,
'orders_foods_changes' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Admin.OrdersFoods'
},
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'_joinData' => true
],
'[original]' => [
'_joinData' => [
'quantity' => '1',
'orders_foods_changes' => [
(int) 0 => [
'component_quantity' => (int) 25,
'component_id' => (int) 1,
'order_food_id' => (int) 1,
'type' => 'ADD',
'element_num' => (int) 1,
'id' => (int) 2
]
]
]
],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Admin.Foods'
}
],
'price' => (float) 15,
'shop_id' => (int) 1,
'[new]' => true,
'[accessible]' => [
'*' => true
],
'[dirty]' => [
'user_id' => true,
'type' => true,
'city' => true,
'postal_code' => true,
'street' => true,
'house' => true,
'phone' => true,
'foods' => true,
'price' => true,
'shop_id' => true
],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Admin.Orders'
}
As I can see from sql log Cake does not even tries to save anything to a last table.
I would be grateful for any help.
So the main problem was that by default cake save method makes only one level association.
By default the save() method will also save one level of associations
When I've added associated it all went well.
if ($this->Orders->save($order, [
'associated' => ['Foods._joinData.OrdersFoodsChanges']
]))
I'm playing with RoseDB::Object on the employees test dataset, and for some reason, I can't get my foreign key relationships ('department' and 'employee') to work on the DeptEmp object. (Class structure below).
When I try $e->dept_emp->[0]->department, I get:
Can't locate object method "department" via package "My::FakeEmployees::DeptEmp"
Methods for the following relationships and foreign keys were deferred and
then never actually created in the class My::FakeEmployees::DeptEmp.
TYPE NAME
---- ----
Foreign Key department
Foreign Key employee
I'm sure I have something set up wrong in my class structure, but what?
CLASS STRUCTURE (some classes omitted for clarity):
I created the various objects using the instructions in the RDBO tutorial:
package My::FakeEmployees::Employee;
use strict;
use base qw(My::FakeEmployees::DB::Object);
__PACKAGE__->meta->setup(
table => 'employees',
columns => [
emp_no => { type => 'serial', not_null => 1 },
birth_date => { type => 'date', not_null => 1 },
first_name => { type => 'varchar', length => 14, not_null => 1 },
last_name => { type => 'varchar', length => 16, not_null => 1 },
gender => { type => 'enum', check_in => [ 'M', 'F' ], not_null => 1 },
hire_date => { type => 'date', not_null => 1 },
],
primary_key_columns => ['emp_no'],
'relationships' => [
'departments' => {
'type' => 'many to many',
'map_class' => 'My::FakeEmployees::DeptEmp',
},
'dept_emp' => {
'type' => 'one to many',
'class' => 'My::FakeEmployees::DeptEmp',
'column_map' => { 'emp_no' => 'emp_no' },
},
'dept_manager' => {
'type' => 'one to many',
'class' => 'My::FakeEmployees::DeptManager',
'column_map' => { 'emp_no' => 'emp_no' },
},
'salaries' => {
'type' => 'one to many',
'class' => 'My::FakeEmployees::Salary',
'column_map' => { 'emp_no' => 'emp_no' },
},
'titles' => {
'type' => 'one to many',
'class' => 'My::FakeEmployees::Title',
'column_map' => { 'emp_no' => 'emp_no' },
},
],
);
__PACKAGE__->meta->make_manager_class('employees');
1;
package My::FakeEmployees::DeptEmp;
use strict;
use base qw(My::FakeEmployees::DB::Object);
__PACKAGE__->meta->setup(
table => 'dept_emp',
columns => [
dept_no => { type => 'character', not_null => 1 },
emp_no => { type => 'integer', not_null => 1 },
from_date => { type => 'date' },
to_date => { type => 'date' },
],
primary_key_columns => [ 'emp_no', 'dept_no' ],
foreign_keys => [
department => {
class => 'My::FakeEmployees::Departments',
key_columns => { dept_no => 'dept_no' },
},
employee => {
class => 'My::FakeEmployees::Employees',
key_columns => { emp_no => 'emp_no' },
},
],
);
__PACKAGE__->meta->make_manager_class('dept_emp');
1;
package My::FakeEmployees::Department;
use strict;
use base qw(My::FakeEmployees::DB::Object);
__PACKAGE__->meta->setup(
table => 'departments',
columns => [
dept_no => { type => 'character', length => 4, not_null => 1 },
dept_name => { type => 'varchar', length => 40, not_null => 1 },
],
primary_key_columns => ['dept_no'],
unique_key => ['dept_name'],
'relationships' => [
'employees' => {
'type' => 'many to many',
'map_class' => 'My::FakeEmployees::DeptEmp',
},
],
);
__PACKAGE__->meta->make_manager_class('departments');
1;
Your foreign key has a typo:
foreign_keys => [
department => {
class => 'My::FakeEmployees::Departments',
That should be 'Department', not 'Departments'
It turned out to be a mistake in my code. These lines in DeptEmp.pm:
foreign_keys => [
department => {
class => 'My::FakeEmployees::Departments',
key_columns => { dept_no => 'dept_no' },
},
employee => {
class => 'My::FakeEmployees::Employees',
key_columns => { emp_no => 'emp_no' },
},
],
Have incorrect class names. It should be My::FakeEmployees::Employee and My::FakeEmployees::Department. Singular, not plural.
I have read Saving Entities and Patching HasMany and BelongsToMany but I'm having trouble with patchEntities() because it doesn't seem to merge the data. After patching, the result of $entities is 1 'empty'/'new' record instead of 2 containing an id. Saving the entity results in a foreign key error.
I am new to CakePHP 3.0 so I may very well do something wrong here. Can someone help me?
Thanks!
My code:
if ($this->request->is(['patch', 'post', 'put'])) {
$list = $this->RecipyIngredients->find()
->contain(['Ingredients', 'Quantities'])
->where(['RecipyIngredients.recipy_id' => $recipy_id])
->toArray();
$entities = $this->RecipyIngredients->patchEntities($list, $this->request->data);
debug($entities);
foreach ($entities as $entity) {
//$this->RecipyIngredients->save($entity);
//debug($entity);
}
}
The various results:
debug($this->request->data);
[
'RecipyIngredients' => [
(int) 0 => [
'id' => '1',
'amount' => '25',
'quantity_id' => '1',
'ingredient_id' => '269',
'remark' => ''
],
(int) 1 => [
'id' => '2',
'amount' => '300',
'quantity_id' => '1',
'ingredient_id' => '88',
'remark' => ''
],
]
]
debug($list);
[
(int) 0 => object(App\Model\Entity\RecipyIngredient) {
'id' => (int) 1,
'recipy_id' => (int) 1,
'ingredient_id' => (int) 269,
'quantity_id' => (int) 1,
'amount' => '25',
'amount_in_gram' => (int) 25,
'remark' => '',
'grouping_term' => null,
'version' => (int) 1,
'created' => null,
'modified' => null,
'quantity' => object(App\Model\Entity\Quantity) {
'id' => (int) 1,
'name' => 'gram',
'[new]' => false,
'[accessible]' => [
'name' => true,
'ingredients' => true,
'recipy_ingredients' => true,
'shoppinglist' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Quantities'
},
'ingredient' => object(App\Model\Entity\Ingredient) {
'id' => (int) 269,
'name' => 'citroensap',
'average_weight' => null,
'recipy_id' => null,
'quantity_id' => null,
'[new]' => false,
'[accessible]' => [
'name' => true,
'average_weight' => true,
'recipy_id' => true,
'quantity_id' => true,
'recipy' => true,
'quantity' => true,
'shoppinglist' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Ingredients'
},
'[new]' => false,
'[accessible]' => [
'recipy_id' => true,
'ingredient_id' => true,
'quantity_id' => true,
'amount' => true,
'amount_in_gram' => true,
'remark' => true,
'grouping_term' => true,
'version' => true,
'recipy' => true,
'ingredient' => true,
'quantity' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'RecipyIngredients'
},
(int) 1 => object(App\Model\Entity\RecipyIngredient) {
'id' => (int) 2,
'recipy_id' => (int) 1,
'ingredient_id' => (int) 88,
'quantity_id' => (int) 1,
'amount' => '300',
'amount_in_gram' => (int) 300,
'remark' => 'Gewicht zonder schil',
'grouping_term' => null,
'version' => (int) 1,
'created' => null,
'modified' => null,
'quantity' => object(App\Model\Entity\Quantity) {
'id' => (int) 1,
'name' => 'gram',
'[new]' => false,
'[accessible]' => [
'name' => true,
'ingredients' => true,
'recipy_ingredients' => true,
'shoppinglist' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Quantities'
},
'ingredient' => object(App\Model\Entity\Ingredient) {
'id' => (int) 88,
'name' => 'banaan',
'average_weight' => null,
'recipy_id' => null,
'quantity_id' => null,
'[new]' => false,
'[accessible]' => [
'name' => true,
'average_weight' => true,
'recipy_id' => true,
'quantity_id' => true,
'recipy' => true,
'quantity' => true,
'shoppinglist' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Ingredients'
},
'[new]' => false,
'[accessible]' => [
'recipy_id' => true,
'ingredient_id' => true,
'quantity_id' => true,
'amount' => true,
'amount_in_gram' => true,
'remark' => true,
'grouping_term' => true,
'version' => true,
'recipy' => true,
'ingredient' => true,
'quantity' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'RecipyIngredients'
}
]
debug($entities);
[
(int) 0 => object(App\Model\Entity\RecipyIngredient) {
'[new]' => true,
'[accessible]' => [
'recipy_id' => true,
'ingredient_id' => true,
'quantity_id' => true,
'amount' => true,
'amount_in_gram' => true,
'remark' => true,
'grouping_term' => true,
'version' => true,
'recipy' => true,
'ingredient' => true,
'quantity' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'RecipyIngredients'
}
]
OK, looked in the sources and the problem lay in the fact the table name was in $this->request->data.
I changed the patchEntities() line to:
$entities = $this->RecipyIngredients->patchEntities($list, $this->request->data['RecipyIngredients']);
and all was well!
I update an entity (so same id) and I get a validation error on a field which has a 'unique' rule.
I verified in the db that there is no an existing identical field and so I don't understand why I have this error as I update the record so obviously the field exists already because it's itself!
Is it a problem to have a 'unique' rule on patchEntity()?
[
'site_name' => '...',
'datas' => object(App\Model\Entity\User) {
'id' => (int) 653,
'owner_id' => (int) 611,
'extraemails' => [
],
'owner' => object(App\Model\Entity\Owner) {
'id' => (int) 611,
'company' => 'This is the Company name',
'created' => object(Cake\I18n\Time) {
'time' => '2015-06-06T18:07:17+0000',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'modified' => object(Cake\I18n\Time) {
'time' => '2015-06-17T02:44:36+0000',
'timezone' => 'UTC',
'fixedNowTime' => false
},
'[new]' => false,
'[accessible]' => [
'email' => true,
'phone' => true,
'phone2' => true,
'fax' => true,
'company' => true,
'tva_number' => true,
'address' => true,
'postcode' => true,
'city' => true,
'country_id' => true,
'users' => true,
'username' => true,
'origin' => true
],
'[dirty]' => [
'email' => true,
'phone' => true,
'postcode' => true,
'city' => true
],
'[original]' => [
'email' => '...',
'phone' => '...',
'postcode' => '...',
'city' => '...'
],
'[virtual]' => [],
'[errors]' => [
'company' => [
'unique' => 'This company name exists already.'
]
],
'[repository]' => 'Owners'
},
....
EDIT patchEntity() call added
$user = $this->Users->patchEntity($site->users[0], [
'email' => $this->siteDatas['userEmail'],
'phone' => $this->siteDatas['ownerPhone'],
'role' => 'owner',
'active' => 1,
'extraemails' => $this->siteDatas['extraemails'],
'owner' => [
'company' => $this->siteDatas['ownerName'],
'email' => $this->siteDatas['ownerEmail'],
'phone' => $this->siteDatas['ownerPhone'],
'address' => $this->siteDatas['ownerAddress'],
'postcode' => $this->siteDatas['ownerPostcode'],
'city' => $this->siteDatas['ownerCity'],
'country_id' => $this->siteDatas['countryId'],
'web' => $this->siteDatas['ownerWeb'],
'origin' => 'sitra',
],
],
[
'validate' => 'import',
'associated' => [
'Extraemails',
'Owners' => [
'validate' => 'import'
]
]
]);
if ($user->errors()) {
// Here is where I get the 'unique' error
}
So again I verified that no other record in the table have the same 'company' name.
and as you can see in the debug() at the begining of my post, I have a owner->id and it's really the one I want to modify.
Here is the validator
public function validationImport(Validator $validator) {
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create')
->notEmpty('company')
->add('company', 'unique', ['rule' => 'validateUnique', 'provider' => 'table', 'message' => __("This company exists already.")])
...
])
;
return $validator;
}
//in my model
public function initialize (array $config)
{
$this->addBehavior('Timestamp');
$this->belongsTo('Users');
}
//in my controller
$query = $this->Articles->find('all')->contain(['users']);
/src/Controller/ArticlesController.php (line 39)
object(Cake\ORM\Query) {
'sql' => 'SELECT Articles.id AS `Articles__id`, Articles.title AS `Articles__title`, Articles.body AS `Articles__body`, Articles.created AS `Articles__created`, Articles.modified AS `Articles__modified`, Articles.is_delete AS `Articles__is_delete`, Articles.user_id AS `Articles__user_id`, Users.id AS `Users__id`, Users.username AS `Users__username`, Users.password AS `Users__password`, Users.role AS `Users__role`, Users.created AS `Users__created`, Users.modified AS `Users__modified` FROM articles Articles LEFT JOIN users Users ON Users.id = (Articles.user_id)',
'params' => [],
'defaultTypes' => [
'Articles.id' => 'integer',
'id' => 'integer',
'Articles.title' => 'string',
'title' => 'string',
'Articles.body' => 'text',
'body' => 'text',
'Articles.created' => 'datetime',
'created' => 'datetime',
'Articles.modified' => 'datetime',
'modified' => 'datetime',
'Articles.is_delete' => 'integer',
'is_delete' => 'integer',
'Articles.user_id' => 'integer',
'user_id' => 'integer'
],
'decorators' => (int) 0,
'executed' => false,
'hydrate' => true,
'buffered' => true,
'formatters' => (int) 0,
'mapReducers' => (int) 0,
'contain' => [
'users' => []
],
'matching' => [],
'extraOptions' => [],
'repository' => object(App\Model\Table\ArticlesTable) {
'table' => 'articles',
'alias' => 'Articles',
'entityClass' => 'App\Model\Entity\Article',
'associations' => [
(int) 0 => 'users'
],
'behaviors' => [
(int) 0 => 'Timestamp'
],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
}
You are debugging the query and not the result. To see the contents you can try:
debug($query->toArray())