Saving related model data (3 levels) - cakephp

Really struggling with saving model info a few levels down.
Firstly, I have a expenseClaim – that hasMany expenses (expenses belongTo expenseClaim).
Expenses HABTM ExpenseCode. (these are things like train fare, petrol costs etc).
So, I have a Add a new Expense page – (ExpenseClaimsController /add).
This kinda looks a bit like a spreadsheet and it allows you to enter multiple rows (each row being a expense). On each row theres a drop down to select the expenseCode. The issue is that the expenseCode is not getting written to the join table (expenses_expense_codes).
If I add a single expense, through the unused and soon to be removed expenseController /add it works fine, so the issue is saving assoisiated models, models. Cant figure out how to do this as expenseCode is not directly related to the expenseClaim model and therefore not saving when I do ExpenseClaimsController /add.
Hope that makes sense….
Heres my ExpenseClaimsController code:
public function add() {
if ($this->request->is('post')) {
//debug($this->request->data);
// Test
$this->loadModel('ExpenseCode');
// Create the claim and the expenses
$this->ExpenseClaim->create();
$this->ExpenseClaim->Expense->create();
// Set the user ID
$this->request->data['ExpenseClaim']['user_id'] = $this->Auth->user('id');
// Set the claim status based on which submit btn was pressed
if ($this->request->data['submit'] == 'Submit') {
$this->request->data['ExpenseClaim']['claim_status_id'] = '2';
} else {
$this->request->data['ExpenseClaim']['claim_status_id'] = '1';
}
// Set the claim status
$now = date('Y-m-d H:i:s');
$this->request->data['ExpenseClaim']['date_submitted'] = $now;
// Save both expenses and the expense claim
if ($this->ExpenseClaim->saveAll($this->request->data)) {
$this->Session->setFlash('The expense claim has been saved', 'flash_success');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('The expense claim could not be saved. Please, try again.', 'flash_failure');
}
}
$users = $this->ExpenseClaim->User->find('list');
$claimStatuses = $this->ExpenseClaim->ClaimStatus->find('list');
$expenseCodes = $this->ExpenseClaim->Expense->ExpenseCode->find('list');
$mileageRate = $this->Auth->user('mileage_rate');
$this->set(compact('users', 'claimStatuses', 'expenseCodes', 'mileageRate'));
// Set errors for top of page
$this->set('errors', $this->ExpenseClaim->validationErrors);
}
Can anyone point me in the right direction? Thanks in advance.

Managed to track down the issue, I had to rename the field in ExpenseClaim add to
$this->Form->input('Expense.0.ExpenseCode.ExpenseCode');
This then solved the issue.
Hopefully this will help someone.

Related

Add a user in Cakephp

There is a problem when I write an add() function for UsersController.
public function add() {
if ($this->request->is('post')) {
$this->request->data['User']['book_id'] = $this->Book('id');
if ($this->User->saveAssociated($this->request->data)){
$this->request->data['User']['book_id'] = "ff";
$this->Session->setFlash(__('Save User'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('User Error.'));
}
}
If I add a User I want to save the book ID in my User book_id.
Anyone know how to deal with this problem? Thanks!
When you're adding a new user, does he get to select a book from a drop down(in the form)? If so, $this->request->data['User']['book_id'] will already contain the Book id.
There's no need to explicitly write $this->request->data['User']['book_id'] = $this->Book('id'); like you have done.
The way I see it, the add.ctp view file should contain a select box containing a list of all books which the user can select. On selecting one of those and submitting the form, $this->request->data['User']['book_id'] will automatically store the book_id, without having to write anything in the controller.
Please specify the add.ctp form fields so that I can assist you better.
Thanks!

Weird problems while getting ID just after saving data

I have different models which are an extension of another one.
classes (SubModel1, SubModel2, ..,6) extends -> HighModel extends -> Appmodel
Everytime I save data in each submodel I call a function in my HighModel to save the id of the just saved SubModel. It works perfectly with five SubModels, but in one the id is always: ($shouldBeThisId - 1)in both add and edit functions.... o_O
Here's my add function:
public function add() {
if ($this->request->is('post')) {
$this->M18Tab->create();
if ($this->M18Tab->save($this->request->data)) {
$data = $this->M18Tab->findById($this->M18Tab->id); //<---problem's here
if($this->M18Tab->M18Model->saveVersion($data)){
$this->Session->setFlash(__('The m18 tab has been saved'));
$this->redirect(array('action' => 'view', $this->M18Tab->id));
} else {
$this->Session->setFlash(__('Error with versioning system'));
}
} else {
$this->Session->setFlash(__('The m18 tab could not be saved. Please, try again.'));
}
}
//view variables
}
ok. so after saving I recall the "just saved data" and pass it to $this->SubModel->HighModel->saveVersion($data). and the weird thing is that if I try to force the id to find:
$data = $this->M18Tab->findById(33);
it'll still find the id preceding the just inserted one :0.
what could this be caused by? the code is the same for all 6 models and in only one I have this issue..
This is more of a comment/suggestion than an answer, but anyway...
If you're adding a new record, after calling save, you can get it's ID via:
$this->MyModel->getInsertId();
See that method in the cookbook. I know the id should also be available at $this->MyModel->id, but since it's not working in this case, you might want to try:
$data = $this->M18Tab->findById($this->M18Tab->getInsertId());

CakePHP - Writing to 2 db tables from the same view

I'm trying to write a small expenses cake app. Basicaly I have a expenseClaim that hasMany Expenses (expense belongsTo expenseClaim). When you add/edit a expenseClaim I want to be able to add multiple expenses for that expense claim from within that view. Could someone point me in the right direction?
Any tutorials / sample code would be massively appreciated. Thanks in advance
using cake 2.1
Put in expenseClaim/add:
$this->expenseClaim->Expense->create();
It should work if the relationship is well set in the model.
If not,
$this->loadModel('Expense');
$this->Expense->create();
should always work.
Edit:
$data=array
(
[Expense] => Array
(
[fieldname1] => 'value'
[fieldname2] => 'value'
)
)
$this->loadModel('Expense');
$this->Expense->create();
if ($this->Expense->save($data)) {
$this->Session->setFlash(__('Done.'));
} else {
$this->Session->setFlash(__('Failure.'));
}
Edit2: if you want to pass data from the view:
if ($this->request->is('post')) {
$this->loadModel('Expense');
$this->Expense->create();
if ($this->Expense->save($this->request->data)) {
$this->Session->setFlash(__('Done.'));
} else {
$this->Session->setFlash(__('Failure'));
}
}
The request is created automatically if you use the form helper in the view.

CakePHP - Passing Data Between Models

This is my last hope...I have been trying to figure this out all day and I am out of gas. I have an appointment application that an operator inputs phone, business, name, and call result (Customers Controller). The call result then goes to the Appointments controller. Lets say the operator setups up an appointment, I then now need to setup an appointment for the customer I just entered. But when I try and setup a new appointment for the new customer I just get sent back to the Appointments index view instead of the form. What am I doing wrong? I need some other eyes on this. My development team has all been laid off and I am the last one left, so I don't have anyone to bounce ideas and code off. Please help. I don't even know if I am asking the right question at this point.
function step1() {
$this->set('title_for_layout','Make a New Call');
if (!empty($this->data)) {
$this->Customer->create();
$this->data['Customer']['user_id'] = $this->Auth->user('id');
if ($this->Customer->save($this->data)) {
$this->Session->setFlash(__('The customer has been saved', true));
//??? WHAT DO I PUT HERE TO GO TO THE APPOINTMENTS CONTROLLER WITH THIS CUSTOMER DATA
} else {
$this->Session->setFlash(__('The customer could not be saved. Please, try again.', true));
}
}
}
Try this after saving the data
if ($this->Customer->save($this->data)) {
$this->Session->setFlash(__('The customer has been saved', true));
$id = $this->ModelName->getInsertID();
$this->redirect("customers/index/$id");
Now you've the id and fetch the data over there.
Or if you want to pass the entire array to that function then try this link simple cakephp problem
Where did you get $customer ? it isn't initialize
so you can save data in session
but it isn't good idea
$this->Session->write('data',$this->data);
also uoy can transfer customer id to another controller like this
$this->redirect("/appointments /step2/{$id}/");
// this is in appointments controller
function step2($id = null){
if($id){
$this->loadModel('Customer');
$customer = $this->Customer->findById($id);
}
}
something like this, hope it helps

Saving multiple records for multiple models cakephp

Hey guys, I'm super stuck after a long night.
I'm creating an app where you can create food menus dynamically, and have relationships set up as such: Menu hasMany Widget, Widget hasMany WidgetItem (and of course, WidgetItem belongsTo Widget, Widget belongsTo Menu).
The menu is created first, then the user is redirected to addSectionsToMenu, where I have set up multiple Widgets (title input), respectively with multiple items (menu items).
My widgets save and attach to the menu fine, but my WidgetItems don't save. My models are set up fine I am sure, and I spent 2 hours sorting out my $data structure. I just think I need to figure something out here.
Please help!
Thanks,
~Harley
function addSectionsToMenu($menu_id = null){
$this->layout = 'admin';
$this->set('menu_id', $menu_id);
$this->set('menu', $this->Widget->Menu->findById($menu_id));
if (!$menu_id && empty($this->data)) { $this->Session->setFlash(__('Pick a menu to add to please :)', true)); }
$saveSuccess = false;
if(!empty($this->data['Widget'])) {
$widget_count = 0;
foreach($this->data['Widget'] as $widgetKey => $widget) :
if($this->Widget->saveAll($widget)) : $saveSuccess = true; endif;
$widget_count++;
endforeach;
if ($saveSuccess) {
$this->Session->setFlash(__($widget_count.' sections have been added to the Menu', true));
$this->redirect(array('controller' => 'menus', 'action' => 'index'));
} else {
$this->Session->setFlash(__('The Menu and Sections could not be saved. Please, try again.', true));
}
}
}
I've had problems saving multiple models at once and I solved it by adjusting the validation option.
$this->Invoice->saveAll($this->data, array('validate' => true))
The explanation of the options array doesn't make complete sense to me, but the default was causing my insert to fail because the related records were not getting their foreign key from the insert of the parent record. Changing the option to "first" (the default) to "true" solved the problem and the rows are showing up in the database correctly.

Resources