Saving User and Detail rows with Cake 2.4.5 - cakephp

I am very new to cake and I was wondering how i would be able to create a new user and also be able to create the contact details
database is like so
Users
user_id
contact_detail_id
password
role_id
username
Contact_Details
contact_detail_id
address1
address2
and many other fields
In the User model I have assigned public $hasOne = array('ContactDetail');
Since the user will have one contactdetail
Now what I need to know is how would this would be saved in the add method as many said to use the saveassociated although this doesn't seem to be working.
The add view is like so and from my understanding this is correct
<?php echo $this->Form->create('User', array('action' => 'add')); ?>
<fieldset>
<legend><?php echo __('Add User'); ?></legend>
<?php
echo $this->Form->input('User.username');
echo $this->Form->input('User.password');
echo $this->Form->input('roles');
echo $this->Form->input('ContactDetail.name');
echo $this->Form->input('ContactDetail.surname');
echo $this->Form->input('ContactDetail.address1');
echo $this->Form->input('ContactDetail.address2');
echo $this->Form->input('ContactDetail.country');
echo $this->Form->input('ContactDetail.email');
echo $this->Form->input('ContactDetail.fax');
?>
<label>Are you interested in buying property in Malta?</label>
<?php
$interest_buy = array('0'=>'no','1' => 'yes');
echo $this->Form->input('ContactDetail.interest_buy_property',array('type'=>'radio','options'=>$interest_buy,'value'=>'0','legend'=>FALSE));
?>
<label>Are you interested in renting property in Malta?</label>
<?php
$interest_rent = array('0'=>'no','1' => 'yes');
echo $this->Form->input('ContactDetail.interest_rent_property',array('type'=>'radio','options'=>$interest_rent,'value'=>'0','legend'=>FALSE));
echo $this->Form->input('ContactDetail.mobile');
echo $this->Form->input('ContactDetail.phone');
echo $this->Form->input('ContactDetail.postcode');
echo $this->Form->input('ContactDetail.town');
echo $this->Form->input('ContactDetail.newsletter',array('type'=>'checkbox','label'=>'Would you like to register for the newsletter?' ,'checked'=>'1','legend'=>FALSE,));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>

Please see Arun explanation about what to put in your model first and then, you can use $this->User->saveAll(); or $this->User->saveAssociated(); to save both tables at the same time.
If you want to save ContactDetail first and then save User, You can do this second option, but it is not recomended.
$this->User->ContactDetail->create();
$this->User->ContactDetail->save($this->request->data);`
this->request->data['User']['contact_detail_id'] = $this->User->ContactDetail->id`;
$this->User->Create();
$this->User->save($this->request->data);`
But I prefer the first option, to try the first option again,
Note: Make sure ContactDetail and User relationship are there in the model like this in User Model
public $hasOne= array(
'ContactDetail' => array(
'className' => 'ContactDetail',
'foreignKey' => 'contact_detail_id'
)
);
Hope it helps.

In the first look into your database, you should use the following database structure, this will help you in a more directions:
User Model
id
username
password
role_id
ContactDetail Model
id
user_id
address1
address2
Define hasMany model relationship in the User Model with ContactDetail like:
$hasMany => array('ContactDetail');
Now populate an array of Contact details with (id => address1) pair using:
$this->ContactDetail->find('list', array('conditions' => array('user_id' => $user_id)),
'fields' => array('ContactDetail.id', 'ContactDetail.address1')));
Now to save an associated details, use SaveAssociated Method.

Related

Editing associated models data in cakephp

I'm using CakePHP 2.3.6. I have some Models in my project, which are associated and I defined the association explicitly. Now, I have an Edit form, where I retrieve all the models data, and trying to edit those data in the corresponding models. But, edition is not happening, instead, new rows are created in the associated tables.
Here is my associations among the models :
in the model User.php :
public $hasMany=array('Education'=>array(
'className'=>'Education
'foreignKey'=>'user_id'
),
'Experience'=>array(
'className'=>'Experience',
'foreignKey'=>'user_id'
),
'Employment'=>array(
'className'=>'Employment',
'foreignKey'=>'user_id'
),
'ProfessionalQualification'=>array(
'className'=>'ProfessionalQualification',
'foreignKey'=>'user_id'
)
)
in the model Education.php :
public $belongsTo=array('User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
)
)
in the model Experience.php
public $belongsTo=array('User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
)
)
in the model Employment.php :
public $belongsTo=array('User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
)
)
in the model ProfessionalQualification.php :
public $belongsTo=array('User'=>array(
'className'=>'User',
'foreignKey'=>'user_id'
)
)
Now, in the Edit form (View/Users/edit.ctp) :
echo $this->Form->create('User');
echo $this->Form->input('User.name');
echo $this->Form->input('User.username');
echo $this->Form->input('User.password');
echo $this->Form->input('User.address');
echo $this->Form->input('User.phone');
echo $this->Form->input('Education.0.degree');
echo $this->Form->input('Education.0.passing_year');
echo $this->Form->input('Experience.0.title');
echo $this->Form->input('Experience.0.description');
echo $this->Form->input('Employment.0.company');
echo $this->Form->input('Employment.0.description');
echo $this->Form->input('ProfessionalQualification.0.certificate');
echo $this->Form->input('ProfessionalQualification.0.description');
echo $this->Form->submit('Save');
echo $this->Form->end();
in the UsersController.php controller :
public function edit(){
$this->set('title_for_layout','Edit CV');
if(!AuthComponent::user('id'))
throw new NotFoundException(__('Invalid User'));
$user=$this->User->findById(AuthComponent::user('id'));
if(!$user)
throw new NotFoundException(__('Invalid User'));
if($this->request->is('post') || $this->request->is('put')){
if(!$this->User->saveAll($this->request->data)){
$this->Session->setFlash('Sorry, your info could not be saved. Please, try again.');
$this->redirect(array('action'=>'edit'));
}
}
if(!$this->request->data)
$this->request->data=$user;
}
Here, I am trying saveAll() function on User model. I Also tried using save() & saveAssociated() functions, but same result. It doesn't change the corresponding rows in the tables, instead, it creates a new row in all tables, accept the users table, this table successfully gets the new values and updates the values.
What should I do ? Please help me.
Thanks
Here is a way to make it works (in theory) but I'm not sure it's the best and, it's not "secure": Adding the id for related field in your form, with hidden field, like so:
echo $this->Form->create('User');
echo $this->Form->hidden('User.id');
echo $this->Form->input('User.name');
/* ... */
echo $this->Form->hidden('Education.0.id');
echo $this->Form->input('Education.0.degree');
/* ... */
echo $this->Form->hidden('Employment.0.id');
echo $this->Form->input('Employment.0.company');
/* ... */
echo $this->Form->submit('Save');
echo $this->Form->end();
You should check in your controller that the id of your associated models match the id of your main model, if not people will be able to edit associated model not linked with their user model.
Edit: This is an edit for further explanation about the discussion in comment.
When you have hasMany relationship, like so:
public $hasMany = array('Experience') ; // In User class
You have to specify ID when saving the relation, if not the Cake engine cannot infer that you want to update a model instead of saving one.
$data = array(
'User' => array(
'id' => 33,
'name' => 'Holt'
),
'Experience' => array(
array(
/* 'id' => 45, */
'name' => 'PHP'
)
)
) ;
$this->User->saveAssociated($data) ;
Here, you know that the User you're refering to is Holt with the id 33, and so you know that the experiences in the following array refers to this user. But, if you don't specify the id field in the Experience array, how the engine would know which experience you're refering to?
If the relation was a belongsTo, it's easy to infer that's the Experience related to user Holt (there is only one Experience per user according to relation belongsTo or hasOne), and by the way you wouldn't have a nested array.
There are different ways to tell the engine you want to update a model, the 2 I use are:
Setting the id value in the data array (like above)
Setting the $this->Model->id value in your controller: This value is implicitely set when you do a $this->Model->read or a $this->Model->find (like you do)
What I'm sure, is that the first option works for associated model (like in the above data array if you uncomment the id), I'm not sure that the second works for associated model, like doing $this->User->Experience->id = ..., you can try it, I cannot check it right now.

Changing table field using 2 different models

I have an IT query system were by users can add their queries, when they add their query the IT department then replies/comments on the query.
How is should work is when the user adds a query it must change the query_type field in the it_queries table to OPEN and when the IT department views the query they reply/comment on it and must change query_type field from OPEN to PENDING then finally when the user has been helped/assisted they should be able to mark the query as closed using a checkbox, that will then change the status from PENDING TO CLOSE.
Not sure if they is a way of setting the constants in the add views and insert in the table.
Obviously i am learning and can someone please guide me on the steps i must take.
Here is my code for the add it_query for the users
<?php echo $this->Form->create('ItQuery'); ?>
<fieldset>
<legend><?php echo __('Add It Query'); ?></legend>
<?php
echo $this->Form->hidden('hr_employee_id',array('value'=>$loggedInId));
echo $this->Form->input('it_query_type_id');
echo $this->Form->input('comment');
echo $this->Form->hidden('status_type', array('value'=>OPEN));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
Here is the code for my comments for IT Department
<?php echo $this->Form->create('ItQueryComment'); ?>
<?php echo __('Add It Query Comment'); ?>
<?php
echo $this->Form->input('it_query_id');
echo $this->Form->input('comment');
echo $this->Form->input('close_query');
?>
<?php echo $this->Form->end(__('Submit')); ?>
Here is the code for my ItQueryComments
public function add() {
if ($this->request->is('post')) {
$this->ItQueryComment->create();
if ($this->ItQueryComment->save($this->request->data)) {
$this->Session->setFlash(__('The it query comment has been saved'));
$this->redirect(array('controller' => 'it_queries','action' => 'view', $this->request->data['ItQueryComment']['it_query_id']));
} else {
$this->Session->setFlash(__('The it query comment could not be saved. Please, try again.'));
}
}
$itQueries = $this->ItQueryComment->ItQuery->find('list');
$hrEmployees = $this->ItQueryComment->HrEmployee->find('list');
$this->set(compact('itQueries', 'hrEmployees'));
}
While saving a comment for a particular Itquery , in your add function of Comments Controller after adding comment to database get its id by using $this->getLastInsertID();
and call function updateAll for Itquery Model and change status of that particular Query to "Pending".

Why I can't see the result of HABTM?

I am using cakephp since few months, and I have a problem today that I don't know why it is not working as always.
I've got three table:
posts
comments
posts_comments
In the models, I set :
Comment Model:
var $hasAndBelongsToMany = array('Post');
Post Model
var $hasAndBelongsToMany = array('Comment');
Then in my controller, for example the PostController:
$this->set('comments', $this->Post->Comment->find('list', array('order' => 'Comment.id')));
And then in my Post View I have :
<?php
echo $this->Form->create('Post');
echo $this->Form->input('name', array('label' => 'Name', 'maxlength' => '100'));
echo $this->Form->input('Comment.Comment', array('label' => 'New Comment', 'type' => 'select', 'multiple' => true));
echo $this->Form->submit('Add', array('class' => 'button'));
?>
In my others projects it always worked !
I always had my "Comment" displayed on the list, but here, I don't know why it is not working, nothing is displayed, did I forgot something ?
Regards,
4m0ni4c.
I don't know if you solved it yet, but according to Cake convention, the HABTM tables should be named alphabeticaly for them to work magically.
This new join table’s name needs to include the names of both models involved, in alphabetical order, and separated with an underscore ( _ ). The contents of the table should be two fields, each foreign keys (which should be integers) pointing to both of the primary keys of the involved models
So your posts_comments table should be comments_posts, unless you change the association directly on Post and Comment model.

cakephp select field of relationed elements for show in a view

I have this in cakephp, I try choose the field to be displayed in the combobox when creating related data in cake php.
<?php echo $this->Form->create('Round'); ?>
<fieldset>
<legend><?php echo __('Add Round'); ?></legend>
<?php
echo $this->Form->input('description');
echo $this->Form->input('text_marked');
echo $this->Form->input('project_id');
echo $this->Form->input('User');
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
I try select one project with project_title, in the table project, not by 'project_id'. Title are not unique but is more descriptive than id. Can I do this in cake php?
The answer was easy,Thus we choose the field to display in the other views that are associated. it was put:
public $displayField = 'titte'
in the Round model.

how to create form in cake php

I am very new in cake php, i want to know how to create form in cake php,please describe,when we go to create a form then what i have to do,like create model and controller everything
In the view file, something like this would work:
<?php
echo $this->Form->create();
echo $this->Form->input('firstname', array('label' => 'Enter your first name:'));
echo $this->Form->input('email', array('label' => 'Enter your email address:'));
echo $this->Form->input('password', array('label' => 'Enter your password:'));
echo $this->Form->end('Save');
?>
In your controller:
if($this->request->is('post')){
$this->User->save( $this->request->data );
}
You can apply some sort of validation in your model, look in the documentation for that.
Best option to learn about cakephp is it's own doc book
But I'm providing you some basic code to create form :
$this->Form->create('ModelName');
$this->Form->input('ModelName.fieldname', array('type'=>'text', 'label'=>'Modified-Name'));
$this->Form->end(__('Submit'));
Here array('type'=>'text'...): type shows which type of input field you want.
(...'label'=>'Modified-Name'): By default it shows field text as fieldname but by using 'label' you can modify your field text.
$this->form->create('controlpage',
array(
'action'=>'controll',
'class'=>'class',
'enctype' => 'multipart/form-data',
'onsubmit'=>'return valid()'
));
Block quote
Create form in html save it as ctp
Block quote
And call it in view. enter code hereUse cake php book to read further.

Resources