CakePHP saving foreignKeys not working - php

I have 3 tables: Computers hasMany Brands, Brands belongsTo Computers and Parts. Now i have these fields in my Brands description,computer_id,part_id. I have the code below to save my data. It will save the description and part_id....But my computer_id does not save at all.
Usually my URL written http://192.168.6.253/computers/brands/add/1 where 1 is computer_id.
How will I save it? Im still beginner in this framework
Controller
public function add($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
//Assign value to link computer_id
$data = $this->Brand->Computer->findById($id);
$this->set('computers', $data);
//assign select values to parts select
$this->set('parts', $this->Brand->Part->find('list',
array('fields' => array('description'))));
if ($this->request->is('post')) {
$this->Brand->create();
if ($this->Brand->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
$this->redirect(array('action' => 'table/'.$id));
} else {
$this->Session->setFlash(__('Unable to add your post.'));
}
}
}
View
<?php
echo $this->Form->create('Brand');
echo $this->Form->input('part_id',array('empty'=>' '));
echo $this->Form->input('description');
echo $this->Form->input('computer_id',array('type'=>hidden));
echo $this->Form->end('Save Post');
?>

If you are not requiring to send the computer id through the form since it's a url param... you can adjust your add function like this
if ($this->request->is('post')) {
$this->request->data['Brand']['computer_id'] = $id; //manually add the id to the request data object
$this->Brand->create();
if ($this->Brand->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
$this->redirect(array('action' => 'table/'.$id));
} else {
$this->Session->setFlash(__('Unable to add your post.'));
}
}
That's a very basic way of doing it without checking for data integrity, anyone could easily change the param to a 2, but it conforms with your current setup.

Related

cakephp 2.x edit field for comparing old and new records

Question : I want to compare the different records before and after edit.
1) i find that it will generate different id to get the corresponding fields ***** $this->set( compact('brands', 'imageTypes')); *****
and auto write into view's fields. But how can i get all input field names ( I want to auto find all the fields record by these two id automatically in case there are some fields change in the future. )
Controller :
function admin_edit(){
$this->BrandImage->id = $id;
if (!$this->BrandImage->exists($id)) {
throw new NotFoundException(__('Invalid brand image'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->BrandImage->save($this->request->data)) {
// $this->Session->setFlash(__('The brand image has been saved'), 'flash/success');
// $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The brand image could not be saved. Please, try again.'), 'flash/error');
}
} else {
$options = array('conditions' => array('BrandImage.' . $this->BrandImage->primaryKey => $id));
$this->request->data = $this->BrandImage->find('first', $options);
debug( $this->request->data['BrandImage']['path']);
}
$brands = $this->BrandImage->Brand->find('list');
$imageTypes = $this->BrandImage->ImageType->find('list');
$this->set( compact('brands', 'imageTypes'));
}

Update existing record in CakePHP

I want to create the following in CakePHP:
Starting page: User enters a loginname which pre exists in the DB. Table name loginname.
Once the user has entered the right loginname, the user continues to the registration form, where the user can add personal data to the existing record.
When the user saves the form, the record with only the loginname has personal data added.
This is what i have:
Logic for starting page:
public function checkCodeRespondent() {
//set var
$password = $this->data['Respondent']['loginname'];
//set condition for hasAny function
$condition = array('Respondent.loginname'=>$password);
//if password matches continue to registreer
if($this->Respondent->hasAny($condition)){
//find data by password
$respondent = $this->findByPass($password);
//set var for current id
$id= $respondent['Respondent']['id'];
//redirect with current id
$this->redirect(array('action' => 'aanmelden', $id));
} else {
//if password does not match, return to index with errormessage
$this->redirect(array('action' => 'index'));
}
}
public function findByPass($pass) {
$respondent = $this->Respondent->find('first', array('conditions' => array('pass' => $pass)));
return $respondent;
}
And this is the logic for saving the data to the record:
public function registreren() {
if($this->request->isPost()) {
$this->Respondent->id = $id;
if ($this->Respondent->save($this->request->data)){
$this->Flash->success(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
}
}
I thought i got my id through the function checkCodeRespondent() , but that's not working. What am i forgetting or what am i doing wrong? If i need to give more info, i'm happy to help ofcourse.
Update: I read that i need to add echo $form->input('id');, only when i debug($this->request); the id value is empty. What do i need to change in my code?
If you have added hidden field for id then just replace:
$this->Respondent->id = $id;
By:
$this->Respondent->id = $this->request->data['Respondent']['id'];
And in your view, give name="data[Respondent][id]" in the hidden field of id like:
<input type="hidden" name="data[Respondent][id]" value="value of id">
that should work fine for you if no other issues out there.

Trying to pass list for a dropdown but can't find variable

I am new to this and I have reached an impasse that has got me stuck for the past day
I have 3 tables Posts,Categories, and Users with a 1-many relationship where a category can have many posts.
The category table simply has two fields : id and cat_desc, with id being set as the primary key
in my postscontroller I have an add function
public function add() {
if ($this->request->is('post')) {
$data = $this->Post->Cat->find('list', ['fields' => array('cat_desc')]);
$this->set('cats', $data);
$this->request->data['Post']['user_id'] = $this->Auth->user('id');
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
}
$this->set('title_for_layout',"'Add a Post");
}
in my view i try to call the list for the dropdown
echo $this->form->create('Post', array('action'=>'add'));
echo $this->form->input('title');
echo $this->Form->input('category', array('options' => array('options'=> $cats))
);
echo $this->form->input('amount');
echo $this->form->input('body');
echo $this->form->end(__('Create a Post', true));
I am getting an undefined variable cats. Any help would be greatly appreciated and I thank you all for your posts as it has helped get me to this point :)
When you first navigate to the page, the request type will be "get". The way your code is, $cats will only be set if the request type is a "post" (so it will only be defined when you submit the form.) Just move the code that sets $cats to outside the if statement if($this->request->is('post'))
//controller
public function add() {
if ($this->request->is('post')) {
$this->request->data['Post']['user_id'] = $this->Auth->user('id');
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
} else {
$cats = $this->Post->Cat->find('list', ['fields' => array('cat_desc')]);
$this->set('cats', $cats);
$this->set('title_for_layout',"'Add a Post");
}
}
//view
echo $this->Form->input('cat_id', $cats, array(options here));

Populate Fields From one Controller, in another.. CAKEPHP

I am currently trying to allow the users to archive events that have already been completed.
Then the event will be viewed in the Archive Table.
So basically I have one archive table, and one event table, and when the user wants to archive the event, they should be able to view the event in the archive add form (which needs to be populated by the $id of the event).
But I do not know how to populate the field.. I have tried setting a value.. but the events are not sessions so that didn't work, and I have also tried setting the $id at the start of the form, but that also didn't work.
Here is the code to my archive function in the events controller.
public function archive($id = null) {
if ($this->request->is('post')) {
$event = $this->Event->read($id);
$archive['Archive'] = $event['Event'];
$archive['Archive']['eventID'] = $archive['Archive']['archiveID'];
unset($archive['Archive']['archiveID']);
$this->loadModel('Archive');
$this->Archive->create();
if ($this->Archive->save($archive)) {
$this->Session->setFlash(__('The event has been archived'));
$this->Event->delete($id);
$this->redirect(array('action' => 'eventmanage'));
} else {
$this->Session->setFlash(__('The event could not be archived. Please, contact the administrator.'));
}
}
}
You need to do one of the following:
Set the values for the fields using $this->request->data in the controller.
public function add($id = null) {
if ($this->request->is('post')) {
[..snip..]
}
$this->loadModel('Event');
$event = $this->Event->read($id);
$this->request->data['Archive'] = $event['Event'];
}
OR
Update the form to set the values.
Update the existing code with the same event read:
public function add($id = null) {
if ($this->request->is('post')) {
[..snip..]
}
$this->loadModel('Event');
$this->set('event', $this->Event->read($id));
}
Then in your form in the Archives/add.ctp file, update each input to reflect the value of the $event.
echo $this->Form->input('eventID', array('type' => 'hidden', 'value' => $event['Event']['id']));
OR
Write a function that will move the record.
Put a button on the Event View called 'Archive'. Create a method in the Event Controller that will archive the event.
public function archive($id = null) {
if ($this->request->is('post')) {
$event = $this->Event->read($id);
$archive['Archive'] = $event['Event'];
$archive['Archive']['event_id'] = $archive['Archive']['id'];
unset($archive['Archive']['id']);
$this->loadModel('Archive');
$this->Archive->create();
if ($this->Archive->save($archive)) {
$this->Session->setFlash(__('The event has been archived'));
$this->Event->delete($id);
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The event could not be archived. Please, contact the administrator.'));
}
}
}

MVC undrestandig

i research about mvc and n-tier architecture different. but i can't understand how model pass data to view in mvc?
for example in cakephp I have an controller and action like this:
function edit($id = null) {
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid user', true));
$this->redirect(array('action' => 'index'));
}
if (!empty($this->data)) {
if ($this->User->save($this->data)) {
$this->Session->setFlash(__('The user has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
}
}
if (empty($this->data)) {
$this->data = $this->User->read(null, $id);
}
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));
}
in this section:
if (!$id && empty($this->data)) {
$this->Session->setFlash(__('Invalid user', true));
$this->redirect(array('action' => 'index'));
}
we check that id passed or not. if have not be set we redirect user. than:
if (!empty($this->data)) {
if ($this->User->save($this->data)) {
$this->Session->setFlash(__('The user has been saved', true));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.', true));
}
}
if submitted data from view we update row in db. then :
if (empty($this->data)) {
$this->data = $this->User->read(null, $id);
}
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));
and if id have been set and if not data submitted its mains the page early opened and data in relation this id will be read from db and displayed in view.
now I can't understanding how and where model pass data to view in this cakephp's standard mvc????
thanks for help.
Models do not send data to the view. controllers do, by calling the set method. controllers use models to get data from database and then send it to the view:
$this->set('myVariable','myValue');
or you can use compact to send complex data at once like in your example:
$groups = $this->User->Group->find('list');
$this->set(compact('groups'));

Categories