CakePHP: Save data in two models - cakephp

In CakePHP I have two models: Clients & Tickets. A client can have many tickets and a ticket can only have 1 client.
When adding a new ticket I want to automatically create a new client by only entering a name. So the form would be:
Name = "Name client" >> Name should be save in Client table en new client_ID in Ticket table
Info = Ticket information >> Save in Ticket table.
"Save"
I'm not sure how this works. I have associations in the model and tried to saveAll but there is no data stored in the Client table. And how do I get the ID in the Ticket table?
Hope someone can point me in the right direction. I've searched for other answers but cant seem to find a solution. Is saveAll the right way to do this?

You should set a php condition before insert values into the table, the sql request 4 exemple return the numbers of repetition of the same ticket_id so if the returned value is greater than 1 the request can't execute else the request insert the values
The function to count number of rows : mysql_num_rows('request');

You can use the callback methods.
If you have defined your relation in the Ticket model with belongsTo Client, it will be accessible from that model.
public $belongsTo = array(
'Client' => array(
'className' => 'Client',
'foreignKey' => 'client_id',
),
);
So, if you want to make a new client before saving the ticket, you can do:
public function beforeSave ($options = array()) {
$this->data['Client']['name'] = $someVar;
$this->Client->save($this->data);
$this->data[$this->alias]['client_id'] = $this->Client->getInsertID();
return true;
}

Related

cakephp Associations Delete not working

I have a table of files and a table of permissions. The idea is that the user can assign permissions to other users to allow them to read, edit, etc. I set up an association so that the files, which I call workspaces, have many permissions. Here is the declaration in the workspaces model linking the permissions model
public $hasMany = array(
'Permission' => array(
'className' => 'Permission',
'foreignKey'=> 'workspace_id',
'dependent' => true
)
);
The problem is that when I go to delete a file, I get an error.
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Permission.id' in 'field list'
SQL Query: SELECT `Permission`.`id` FROM `cadwolfc_workspaces`.`permissions` AS `Permission` WHERE `Permission`.`workspace_id` = 71
Why is cakephp looking for an id parameter in the permissions table when I have clearly defined the workspace_id as the foreign key? I had assumed that by linking the models and then deleting a workspace, the associated permissions would be deleted. That is what I am trying to do here. I don't understand why a select query is being executed when a delete query is what is needed?
Update: The call to delete the workspace item is done through an ajax call by passing the id of the workspace. I have confirmed that $fileid is the correct number.
$this->Workspace->delete($fileid);
Update 2: When I add a column to the permissions table titled 'id' add make its value the appropriate number, then the delete call works fine and all items are deleted. Why is this?

Cakephp insert sql statement

I'd like to insert data into a mysql table using 'the cakephp way'.
I have a multi-stage program that stores data to a session, and toward the end of the program I'd like to write the session data to the database. I could do this using a standard sql insert statement but would like to know how this should be done using cakephp. (Most of the cakephp doc discusses sending data from a webform, and I'd like to manually submit session data.)
Should I manually format the session data in this format and then send this to the model? And if so, is there a helper function for this?
Array
(
[ModelName] => Array
(
[fieldname1] => 'value'
[fieldname2] => 'value'
)
)
Yes, that's the way to do it. There's really no need for a helper function, just use the ones you normally would.
$name = 'Foo';
$city = 'Bar';
$this->ModelName->save(
array(
'name' => $name,
'city' => $city
)
);

CakePHP HABTM JoinTable w/Extra Field

So I have a customers table, a contacts table, and a contacts_customers join table, which also has contact_type_id field which maps to a contact_type table. I have used the information linked to from CakePHP update extra field on HABTM join table in an attempt to come up with a solution, but it's only partly working. I changed the add() method in the ContactCustomersController to
$this->ContactsCustomer->Contact->save($this->data);
$this->ContactsCustomer->create();
if ($this->ContactsCustomer->save($this->data,
array('validate' => 'first'))) {
$this->Session->setFlash(__('The contacts customer has been saved', true));
$this->redirect(array('controller' => 'contacts_customers', 'action' => 'index'));
} else {
$this->Session->setFlash(__('The contacts customer could not be saved. Please, try again.', true));
}
Note the two-part save; this is because using the saveAll() method of the ContactsCustomer model was just out and out failing with no indication of the problem (all that showed up in the SQL log on the resulting page was a BEGIN immediately followed by a ROLLBACK). My assumption here was that this was due to the foreign key constraint between the contacts table and the contacts_customers table, so I opted for the two-part save.
In any event, there are no errors reported in the current code, but the end result is that the appropriate information is saved in the contacts table, but nothing is saved in the contacts_customers join table. The data posted appears to be appropriate according to the FireBug log data:
_method POST
data[Contact][address_1] asdsad
data[Contact][address_2]
data[Contact][city] asdasd
data[Contact][email] jb#sc.net
data[Contact][fax]
data[Contact][first_name] Joe
data[Contact][last_name] Blow
data[Contact][mobile_phon...
data[Contact][office_phon... sdfsdfdf
data[Contact][postal_code... 121212
data[Contact][state] asdas
data[Contact][title]
data[ContactsCustomer][ContactType]
data[ContactsCustomer][ContactType][] 1
data[ContactsCustomer][ContactType][] 2
data[ContactsCustomer][ContactType][] 3
data[ContactsCustomer][Customer] 1
What have I done incorrectly here? Many thanks to any assistance offered!
Relevant model data:
contact.php
var $hasMany = array(
'ContactsCustomer'
);
contact_types.php
var $hasMany = array(
'ContactsCustomer'
);
customer.php
var $hasMany = array(
'ContactsCustomer'
);
contacts_customer.php
var $belongsTo = array(
'Contact', 'ContactType', 'Customer'
);
haven't tested that yet, but I believe $this->data might have been modified by the first save. Just use an extra variable to hold that data.

Trying to make a filter to retrieve data from related models

I have a Post model which hasMany PostField
every post can have several fields stored in the post_fields table..
post_fields has this structure: (id, post_id, name, value)
posts table has some common fields for all posts, but any additional fields should be stored in post_fields table..
I created a search form that is used to filter the posts
when specifying filters for the fields in the posts table, it works fine..
but I want to make the filter to work even on the other fields found in post_fields ..
I can retrieve the posts first then filter them manually, but i want something more efficient !
EXAMPLE: let's suppose that posts are describing some products..
post (id, title, created, price)
post_fields (id, post_id, name, value)
in this case, all posts have title, created and price..
but if a post (id=3) wants to have a weight field, we should do that by creating a record in post_fields, the record should be :
{ id: .. , post_id: 3, name: weight, value: .. }
it's easy now to filter posts according to price (e.g. price between min & max)..
but, what if i want to filter posts according to weight ??
e.g. i want all posts that have weight greater than 10 !!
I would like to achieve this preferably in one query, using joins maybe or subqueries ..
I don't know how to do that in cakePHP, so if any one has an idea, plz HELP !!
even if someone just has an idea but doesn't have details, that could help ...
thanx in advance !
There is no way to search against the children of a hasMany relationship. You will need to run your query against the PostFields model. ie: $this->PostField->find('all', array('conditions'=>array('PostField.name' => 'weight', 'PostField.value' > 10)));
If you want to do a query against both the PostField and Post models at the same time (ie: price < $1.00 and weight > 10, you will need to do a custom query, as CakePHP has no built-in solution for doing so TMK. Should look something like this:
$query = "SELECT ... FROM posts as Post, post_fields as PostField WHERE PostField.name = 'weight' AND PostField.value > 10 AND POST.price < 1.0 AND PostField.post_id = Post.id;"
$posts = $this->Post->query($query);
EDIT:
I would do this. You're not going to get away with doing a single call, but this is still a clean solution.
$postIds = null;
if(/*we need to run query against PostFields*/) {
$conditions = array(
'OR' => array(
array(
'AND' => array(
'PostField.name' => 'weight',
'PostField.value' > 10
)
),
array(
'AND' => array(
'PostField.name' => 'height',
'PostField.value' < 10
)
)
)
);
$fields = array('PostField.id', 'PostField.post_id');
$postIds = $this->Post->PostField->find('list', array('conditions'=>$conditions, 'fields'=>$fields));
}
$conditions = array('Post.price' < 1.0);
if($postIds) {
$conditions['Post.id'] = $postIds;
}
$posts = $this->Post->find('all', array('conditions'=>$conditions));
You should look into using the Containable behavior for your models. This way, you can filter the returned columns as you like. (I think this is the type of filtering you want to do)

cakephp not saving update value to related table, but no errors

Update order function finds all orderlines of current order.
Loops through subtracting quantity ordered from stock level and holding new stock level value in $newstock. All good.
But won't save.
Echoes "success" and the correct value but the database is not updated.
The Order status field does update, with the same code syntax.
It also has the same relationships with the Orderline. (Function called from Orderline Controller)
The table relationships are:
'Product'hasMany = array('Orderline');
'Order' hasMany = array('Orderline');
'Orderline' belongsTo = array('Order', 'Product');
function updateOrder(){
$this->data['Order']['id'] = $this->getOrderid();
$orderproducts = $this->Orderline->find('all',array('conditions' =>
array('Orderline.order_id' => $this->data['Order']['id'])));
foreach($orderproducts as $orderproduct){
$newstock = $orderproduct['Product']['stock']-$orderproduct['Orderline']['quantity'];
$this->data['Product']['stock']= $newstock;
if( $this->Product->saveAll($this->data)){
echo "success" ;
}else{
echo "not saved";
}
}
$this->data['Order']['status']= 1;
$this->Order->saveall($this->data);
}
I want to add that I was running into silent save fails using saveAll because I hadn't cleared the APP/tmp/cache folder.
Solved.
It had actually been adding new rows to the Product table.
This line was missing from the insert in the foreach loop, reminding it to use the current Product id to know where to insert the new data.
$this->data['Product']['id']= $orderproduct['Product']['id'];

Resources