I have a simple form in Cake :
I want to save the informations in the users and companies tables .
Users Table :
Companies table :
I'm in need to get two sql queries .
First of all :
- Insert the new users with a new company id which will be created in companies table .
For instance with this case, testza,
users : (new entry)
testza password company id (new if of the new company entry)
companies (new entry) :
Id (3) Creaz (name) 500 000 (revenue_generated) .
I guess i'm clear :
companies/signup (view)
<div class="page-header">
<h1>Company Registration</h1>
</div>
<?php echo $this->Form->create('Company'); ?>
<?php echo $this->Form->input('User.username',array('label'=>'Login')); ?>
<?php echo $this->Form->input('User.password',array('label'=>'Password')); ?>
<?php echo $this->Form->input('User.passwordconfirm',array('label'=>'Confirm password','type'=>'password')); ?>
<hr>
<?php echo $this->Form->input('Company.company_id',
array(
'label'=>'Company',
'options' => $companies,
'empty' => 'Select Company Name'
));
?>
<?php echo $this->Form->input('Company.revenue_generated',array('label'=>'Revenue Generated')); ?>
<?php echo $this->Form->end('Envoyer'); ?>
the action signup of the Controller CompaniesController
<?php
class CompaniesController extends AppController{
public $uses = array('User');
public function signup() {
$this->loadModel('Company');
$companies = $this->Company->find('list'); //we get the authors from the database
$this->set('companies', $companies);
if($this->request->is('post') || $this->request->is('put') ){
$d = $this->request->data['User'];
$c = $this->request->data['Company'];
if($d['password'] != $d['passwordconfirm']){
$this->Session->setFlash("Les mots de passes ne correspondent pas","notif",array('type'=>'error'));
}
else{
if(empty($d['password']))
unset($d['password']);
if($this->User->save($d) || $this->Company->save($c)){
$this->Session->setFlash("L'utilisateur a bien été enregistré","notif");
}
}
}
}
..............
User Model :
<?php
class User extends AppModel{
public $actsAs = array('Containable');
public $belongsTo = array(
'Town' => array(
'className' => 'Town'
),
'Company' => array(
'className' => 'Company'
)
);
public $recursive = -1;
public $order = 'User.id DESC';
public $validate = array(
'username' => array(
'rule' => 'isUnique',
'allowEmpty' => false,
'message' => "Ce nom d'utilisateur est déja pris"
),
'password' => array(
'rule' => 'notEmpty',
'message' => "Vous ne pouvez pas entrer de mot de pase"
)
);
public function beforeSave($options = array()){
if(!empty($this->data['User']['password'])){
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
return true;
}
}
Company Model :
<?php
class Company extends AppModel{
public $validate = array(
'revenue_generated' => array(
'rule' =>'notEmpty',
'message' => 'Enter Your Generated Revenue.',
'required' => true
)
);
}
Since you are going to use an existing company already in the database from the drop down menu, try saving both models at the same time with Model::saveAssociated(). This will save both records at once for you, and insert the Company id, automatically into the foreign key for the users table: User.company_id on successful save.
Replace your two save() function calls with one call to saveAssociated():
if($this->User->saveAssociated($data)) {
//do something after save.
}
Here is a complete example using your existing code:
$this->set('companies', $this->Company->find('list'));
if($this->request->is(array('post', 'put'))) {
//Dont need to seperate this anymore
//$d = $this->request->data['User'];
//$c = $this->request->data['Company'];
if($this->request->data['User']['password'] != $this->request->data['User']['passwordconfirm']){
$this->Session->setFlash("Les mots de passes ne correspondent pas","notif",array('type'=>'error'));
} else {
if(empty($this->request->data['User']['password']))
unset($this->request->data['User']['password']);
if($this->User->saveAssociated($this->request->data)){
$this->Session->setFlash("L'utilisateur a bien été enregistré","notif");
}
}
}
The Company model is also missing the hasMany relationship for User. Add this to Company model:
public $hasMany = array('User');
Refer to Cake Manual here for documentation on SaveAssociated():
http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array
here is the solution i suggest and i work with, start by saving the company first to generat the id the save the user :
if($this->Company->save($this->request->data['Company'])){
$this->Company->User->save($this->request->data['User']); // if save doesn't work try $this->Company->User->saveAll($this->request->data['User']);
...
}
update :
add the hasmany relation in the company model :
public $hasMany = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'company_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
hope ut helps.
Related
i am new in cakePHP framework with version 2.0 my problem is when i save the data or insert the new record the field is empty or no data to be save how can i fix this. .
My Model
class Post extends AppModel{
public $name = 'posts';
}
My Controller
public function add(){
if($this->request->is('post')){
$this->Post->create();
if($this->Post->save($this->request->data)){
$this->Session->setFlash('The posts was saved');
$this->redirect('index');
}
}
}
My View
echo $this->Form->create('Create Posts');
echo $this->Form->input('title');
echo $this->Form->input('body');
echo $this->Form->end('Save Posts');
You need to put the validation rules in the Post model, Then you can check validate data or not in the controller action before save into model. See the following Model and controller
In Model
class Post extends AppModel{
public $name = 'posts';
public $validate = array(
'title' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'This is can'\t blank'
),
),
'body' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'This is can'\t blank'
),
),
);
}
In Controller
public function add(){
if($this->request->is('post')){
$this->Post->create();
$this->Post->set($this->request->data);
if ($this->Post->validates()) {
// it validated logic
if($this->Post->save($this->request->data)){
$this->Session->setFlash('The posts was saved');
$this->redirect('index');
}
} else {
// didn't validate logic
$errors = $this->Post->validationErrors;
}
}
}
i'm new in CakePHP and i'm having problems in an example i'm building to learn.
I'm building a plugin with 3 models (Categoria,Plato,Imagen)
The relationships between them are the following:
Categoria - Plato (n-n)
Plato - Imagen (1-n)
If I go to Plato view, I get all Imagen by the relationship, but when I access through a category, I can't just reach the Imagen associated with each Plato. Why? What's the problem?
Models code:
Plato:
App::uses('AppModel', 'Model');
class Plato extends ErestaurantAppModel {
public $name = 'Plato';
//public $actsAs = array('Containable');
public $hasAndBelongsToMany = array(
'Categoria' => array(
'className' => 'Categoria',
'joinTable' => 'categorias_platos',
'foreignKey' => 'plato_id',
'associationForeignKey' => 'categoria_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)
);
public $hasMany = array('Imagen' =>
array('foreingkey' => array('plato_id')));
}
Categoria:
App::uses('AppModel', 'Model');
class Categoria extends ErestaurantAppModel {
public $name = 'Categoria';
//public $actsAs = array('Containable');
public $hasAndBelongsToMany = array(
'Plato' => array(
'className' => 'Plato',
'joinTable' => 'categorias_platos',
'foreignKey' => 'categoria_id',
'associationForeignKey' => 'plato_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)
);
}
Imagen:
App::uses('AppModel', 'Model');
class Imagen extends ErestaurantAppModel {
public $name = 'Imagen';
//public $actsAs = array('Containable');
public $belongsTo = array('Plato');
}
Finally, the code I'm launching when i go to a Categoria view.
App::uses('AppController', 'Controller');
class CategoriasController extends ErestaurantAppController {
public $uses = array('Erestaurant.Categoria');
public function index() {
$this->Categoria->recursive = 0;
$this->set('data', $this->Categoria->find('all'));
}
public function view($id = null) {
if (!$this->Categoria->exists($id)) {
throw new NotFoundException(__('Registro inválido.'));
}
/*
$this->Categoria->recursive = -1;
$options = array('conditions' =>
array('Categoria.'.$this->Categoria->primaryKey => $id),
'contain' => array(
'Plato' => array(
'Imagen'
)
)
);
*/
$this->Categoria->recursive = 2;
$options = array('conditions' =>
array('Categoria.'.$this->Categoria->primaryKey => $id));
$this->set('item', $this->Categoria->find('first', $options));
}
}
The commented code you see it's another way I tried, using Containable, but at the end I get error "Plato is not associated with model Imagen"
Database seems all ok, with each table created as needed (categorias, platos, imagens, categorias_platos) and with all foering keys created and trying to keep CakePHP default names.
Thank you!
To access deep relations you must use containable behavior. You have a definition of containable behavior in your model, but for some reason it is commented.
public $actsAs = array('Containable');
Uppon uncommenting this line in your Categoria, you can access deep relations in this way:
$this->Categoria->find('all', array(
'contain'=>array(
'Plato.Imagen'
)
));
...or something like this. For more information plase visit this link Containable Behavior
I have a a form which adds first_name and last_name of user in cakephp.
here is the code
code for view (add.ctp)
<?php
echo $this->Form->create('User');
echo $this->Form->input('first_name',array('label'=>'First Name'));
echo $this->Form->input('last_name',array('label'=>'Last Name'));
echo $this->Form->end('Add User');
?>
code for UserController (UsersController.php)
<?php
public function add(){
if($this->request->is('post')){
$addData = $this->request->data;
$this->User->create();
if($this->User->save($addData)){
$this->Session->setFlash('User has been added successfully');
$this->redirect(array('action'=>'index'));
}
}
}
?>
view code for User Model (UserModel.php)
<?php
class UserModel extends AppModel{
public $validate = array(
'first_name' => array(
'rule' => 'notEmpty',
'message' => 'first name should not be empty.'
),
'last_name' => array(
'rule' => 'notEmpty',
'message' => 'last name should not be empty.'
)
);
}
?>
This is the code I am using, I have seen on cakebook as well and used various other rules, but no validation is working for my form. Can some please help me what could be the reason ?
Thanks in advance!
Your model filename is incorrect. It should be User.php not UserModel.php
please change your file name to user.php if your using table name in mysql as users instead of UserModel.php
and your classname must be like below
<?php
class User extends AppModel{
var $name = 'User';
public $validate = array(
'first_name' => array(
'rule' => 'notEmpty',
'message' => 'first name should not be empty.'
),
'last_name' => array(
'rule' => 'notEmpty',
'message' => 'last name should not be empty.'
)
);
}
?>
Your model name should be User (as your table name and controller name is users).
So try this in your model file(User.php)
<?php
App::uses('AppModel', 'Model');
class User extends AppModel{
public $validate = array(
'first_name' => array(
'rule' => 'notEmpty',
'message' => 'first name should not be empty.'
),
'last_name' => array(
'rule' => 'notEmpty',
'message' => 'last name should not be empty.'
)
);
}
When a user enters data into my form it isn't saving to the database, this is the structure of my tables
Invoice - id, sender_id, receiver_id, template_id
Field - id, name, description, default_value, template_id
fields_invoices - id, invoice_id, field_id, entered_value
here is the invoice model
class Invoice extends AppModel{
var $name='Invoice';
var $hasMany = array(
'FieldsInvoice');
here is the field model
var $hasMany = array(
'FieldsInvoice'
);
and here is the fieldsInvoice model
<?php
class FieldsInvoice extends AppModel {
public $belongsTo = array(
'Field' => array(
'className' => 'Field',
'foreignKey' => 'field_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Invoice' => array(
'className' => 'Invoice',
'foreignKey' => 'invoice_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
here is the create function in the invoices controller
public function create($id)
{
$this->set('title_for_layout', 'Create Invoice');
$this->set('stylesheet_used', 'homestyle');
$this->set('image_used', 'eBOXLogoHome.png');
$this->layout='home_layout';
if (!is_numeric($id)) throw new BadMethodCallException('I need an ID');
$this->Invoice->id = $id;
if (!$this->Invoice->exists()) throw new NotFoundException('Invalid ID');
$this->set('invoice_id',$id);
$names = $this->Invoice->find('list',array(
'fields'=>array('template_id'),
'conditions'=>array('id'=>$id)));
$fields = $this->Field->find('all', array(
'conditions'=>array(
'template_id'=>$names)));
$this->set(compact('fields'));
$this->set(compact('invoice_id'));
$this->set('name',$names);
$this->Invoice->create();
if(empty($this->data)){
$this->data= $this->Field->read($id);
}
else{
if($this->request->is('post'))
{
$this->Invoice->create();
if($this->FieldsInvoice->save($this->request->data, array('deep'=>true)));
{
$this->Session->setFlash('The field has been updated');
$this->redirect(array('controller'=>'invoices', 'action'=>'index'));
}
//else{
$this->Session->setFlash('Could not be saved');
//}
}
}
}
here is the view for the create function
<?php echo $this->Form->create('FieldsInvoice'); ?>
<?php foreach ($fields as $field): ?>
<?php echo $this->Form->hidden('Invoice.id'); ?>
<?php echo $this->Form->hidden($field['Field']['id']); ?>
<?php echo $this->Form->Input($field['Field']['name'], array('default' =>$field['Field']['default_value'])); ?>
<?php endforeach ;?>
<?php echo $this->Form->End('Submit');?>
when debugging the view this is the output received
array(
'Invoice' => array(
'id' => ''
),
'FieldsInvoice' => array(
(int) 5 => '',
'amount' => 'test',
(int) 6 => '',
'description' => 'test1',
(int) 7 => '',
'totalacctowing' => 'test2',
(int) 8 => '',
'pmtinfo' => 'test3'
)
)
Instead of:
$this->Invoice->save($this->request->data);
in your if condition use the following syntax;
$this->Invoice->save($this->request->data, array('deep' => true));
This link will guide you to save associated data.
Have you tried debugging? Try viewing your form data and see if all fields are ok. Use debug() or pr().
Hi all I finally got my validation for my invoices model working 100% but now its thrown off my validation in relationship model(which was working) because now it references everything in the wrong table.
The relationship model is supposed to make sure that a user exists in the users table before you can send them a request.
The invoice model is supposed to make sure that a user has a column with another user in the the relationship table.
how can I change it to make it work properly? At the moment the code completely throws off my entire relationship side of the website.
-relationship model
class Relationship extends AppModel
{
var $name = 'Relationship';
public $useTable = 'relationships_users';
public $primaryKey = 'id';
public $hasMany = array(
'Invoice' =>
array(
'className' => 'Invoice',
'joinTable' => 'invoice',
'foreignKey' => 'invoice_id'));
public $belongsTo = array(
'User' =>array(
'className' => 'User',
'foreignKey' =>'partyone','partytwo',
'associationForeignKey' => 'username',
));
var $validate = array(
'date' => array(
'rule' => array(
'datevalidation',
'systemDate'
),
'message' => 'Current Date and System Date is mismatched'
),
'partytwo' => array(
'userExists' => array(
'rule' => array(
'userExists',
),
'message' => 'That username doesnt exist.'
),
),
);
function datevalidation($field = array(), $compare_field = null)
{
if ($field['date'] > $compare_field)
return TRUE;
else
return FALSE;
}
function userExists($check)
{
$userExists = $this->User->find('count', array('conditions' => array('User.username'=>$check)));
if ($userExists == 1) {
return TRUE;
}
else
return FALSE;
}
-user model
<?php
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel{
public $name = 'User';
public $hasMany = array(
'Relationship' =>
array(
'className' => 'Relationship',
'joinTable' => 'relationships_users',
'foreignKey' => 'id',
'unique' => false,));
public $useTable = 'users';
public $primaryKey = 'id';
public $validate = array(
'username'=>array(
'The username must be between 5 and 15 characters.'=>array(
'rule'=>array('between', 5, 15),
'message'=>'The username must be between 5 and 15 characters.'
),
'That username has already been taken'=>array(
'rule'=>'isUnique',
'message'=>'That username has already been taken.'
)),
'email'=>array(
'Valid email'=>array(
'rule'=>array('email'),
'message'=>'Please enter a valid email address'
)
),
'password'=>array(
'Not Empty'=>array(
'rule'=>'notEmpty',
'message'=>'Please enter your password'
)
),
'Match passwords'=>array(
'rule'=>'matchPasswords',
'message'=>'Your passwords do not match'
)
,
'password_confirmation'=>array(
'Not Empty'=>array(
'rule'=>'notEmpty',
'message'=>'Please confirm your password'
)));
public function matchPasswords($data){
if ($data['password']==$this->data['User']['password_confirmation']){
return true;
}
$this->invalidate('password_confirmation','Your passwords do not match');
return false;
}
public function beforeSave(){
if(isset($this->data['User']['password'])){
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
return true;
}
}
?>
invoice model-
class Invoice extends AppModel{
var $name='Invoice';
//public $useTable = 'invoices';
//public $primaryKey = 'id';
public $belongsTo = array(
'Relationship' =>array(
'className' => 'Relationship',
'foreignKey' =>'relationship_id',
)
);
var $validate = array(
'to' => array(
'relationshipExists' => array(
'rule' => array(
'relationshipExists',
),
'message' => 'sorry you dont have a relationship with that user.'
),
),
);
var $validateTwo = array(
'datecreated'=>array(
'dateHasntExpired' => array(
'rule'=>array(
'dateHasntExpired',
),
'message'=> 'sorry but your relationship has expired.'
),
),
);
public function relationshipExists($check){
$relationshipExists=$this->Relationship->find('count', array(
'conditions' => array(
'Relationship.partyone <>' => current($check),
'Relationship.partytwo' => current($check),
// 'Relationship.active'==true,
// get the value from the passed var
)
));
if ($relationshipExists == true) {
return TRUE;
}
else
return FALSE;
}
public function dateHasntExpired($check){
$dateHasntExpired=$this->Relationship->find('count', array(
'conditions'=>array(
'DATE(Relationship.expirydate) > DATE(Invoice.datecreated)',
)));
if ($dateHasntExpired == true) {
return TRUE;
}
else
return FALSE;
}
}
here is the error that comes up when trying to view current relationship requests
Database Error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Invoice.invoice_id' in 'field list'
SQL Query: SELECT `Invoice`.`id`, `Invoice`.`to`, `Invoice`.`biller`, `Invoice`.`subject`, `Invoice`.`description`, `Invoice`.`amount`, `Invoice`.`datecreated`, `Invoice`.`duedate`, `Invoice`.`invoice_id` FROM `pra_cake`.`invoices` AS `Invoice` WHERE `Invoice`.`invoice_id` IN (97, 98, 99, 101, 104, 105)
Notice: If you want to customize this error message, create
app\View\Errors\pdo_error.ctp
and here is the error i get when trying to view the relationship requests ive sent
Database Error
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Invoice.invoice_id' in 'field list'
SQL Query: SELECT `Invoice`.`id`, `Invoice`.`to`, `Invoice`.`biller`, `Invoice`.`subject`, `Invoice`.`description`, `Invoice`.`amount`, `Invoice`.`datecreated`, `Invoice`.`duedate`, `Invoice`.`invoice_id` FROM `pra_cake`.`invoices` AS `Invoice` WHERE `Invoice`.`invoice_id` IN (97, 98, 99, 101, 104, 105)
Notice: If you want to customize this error message, create app\View\Errors\pdo_error.ctp
needed to use the unbind method in my controllers, here is an example of the unbind method I used throughout my relationship controller.
public function approve($id=null){
$this->set('title_for_layout', 'Relationships');
$this->set('stylesheet_used', 'homestyle');
$this->set('image_used', 'eBOXLogoHome.jpg');
$this->layout='home_layout';
$this->Relationship->unbindModel(array('hasMany'=>array('Invoice')));
if ($this->request->is('get')) {
$this->request->data = $this->Relationship->read(NULL, $id);
} else {
//sets active to 1
$this->Relationship->read(null, $id);
$this->Relationship->set(array('active' => true,));
if ($this->Relationship->save($this->request->data)) {
$this->Session->setFlash('Your post has been updated.');
$this->redirect(array('action' => 'request'));
} else {
$this->Session->setFlash('Unable to update your post.');
}
}
and because this threw errors in my invoice controller I used unbind there as well and here is an example of the unbind I used in invoicescontroller
public function viewInvoice($id = NULL){
$this->set('title_for_layout', 'View invoice');
$this->set('stylesheet_used', 'homestyle');
$this->set('image_used', 'eBOXLogoHome.jpg');
$this->Invoice->unbindModel(array('belongsTo'=>array('Relationship')));
$this->set('invoice', $this->Invoice->read(NULL, $id));
}