while I am updating record it display above error.
message id seems like this - 1536126282209770000
$q = new CDbCriteria(array(
'condition' => 'tokenId = :btokenid',
'params' => array(
':btokenid' => $tokenId,
),
));
$record = self::model()->find($q);
$record->messageId = $messageId;
if (!$record->save()) {
$_errors = current($record->getErrors());
throw new Exception($_errors[0]);
}
I added 2 primary keys for table.
table structure:
After adding primary keys to table need to flush the cache
To refresh the database cache :
Load all tables of the application in the schema
Yii::app()->db->schema->getTables();
clear the cache of all loaded tables
Yii::app()->db->schema->refresh();
If you want to refresh only one table, you can also do :
Yii::app()->db->schema->getTable('tablename', true);
After that It works fine.
Related
I am trying to setup a favourites button on an article. The following code works ...
public function favouriteNotfavouriteArticleParent(Request $request){
$data = [];
$data['user_id'] = Auth::id();
$data['person_id'] = GetPersonData()['id'];
$data['article_id'] = $request->get('article_id');
$data['action'] = $request->get('action');
UserFavourites::updateOrCreate($data,$data);
}
However, i want it to firstly check for any existing values set for that article ID. If it has favourite set and notfavourite is clicked, it should remove the favourite table row.
At the minute it just adds a row for favourite and notfavourite. I've attached a screenshot of the current sql behaviour.
Any help is massively appreciated!
UpdateOrCreate takes two arguments. The first argument is an array of attributes to look for and the second argument is an array of attributes to change. If there isn't a row in the database that has attributes from the first array the arrays will essentially be combined to make a new row in the database.
To achieve what you're after you could do the following:
UserFavourites::updateOrCreate([
'article_id' => $request->input('article_id'),
'user_id' => auth()->id(),
], [
'person_id' => GetPersonData()['id'],
'action' => $request->input('action'),
]);
The above will look for a row that matches the article_id and user_id and then either update the person_id and action for that row or (if the row doesn't exist) create a new row with all the attributes.
i have a code like this ,
$request = Yii::$app->request;
$post = $request->post();
$filesettingid = $post['filesettingid'];
$checkboxValue = $post['selection'];
for($i=0;$i<sizeof($checkboxValue);$i++) {
$store = Yii::$app->db->createCommand('SELECT id FROM store WHERE port='.$checkboxValue[$i])->queryAll();
$storeid = $store[$i]['id'];
Yii::$app->db->createCommand()->insert('tes',
[
'id' => $i+1,
'filesetting_id' => $filesettingid,
'store_id' => $storeid
])->execute();
}
what i want is, each i insert the new data, id will generate automaticly like 1,2,3,4.
the problem in above code is, the ID always be 1.
is it possible to make it real?
so what i want is :
First time insert, id = 1, second is id = 2 , and that is happen automatically.
Have you considered setting database engine to auto increment values with each insert?
Take as an example Yii2 default user table. ID filed is auto incremented, and you don't have to worry about setting it problematically. Every time you send a new insert engine increments ID filed by itself.
See default migration under "advanced template"\console\migrations\m130524_201442_int. (your file name might be different depending on the Yii2 version)
$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string()->notNull()->unique(),
'auth_key' => $this->string(32)->notNull(),
'password_hash' => $this->string()->notNull(),
'password_reset_token' => $this->string()->unique(),
'email' => $this->string()->notNull()->unique(),
'status' => $this->smallInteger()->notNull()->defaultValue(0),
.........
], $tableOptions);
When setting 'id' to primary key database automatically knows to auto increment it. If you already have a table the ID field is not primary key you can use the followign migration:
$this->alterColumn('{{%databaseName}}', 'columnName', $this->integer()->notNull().' AUTO_INCREMENT');
You can also set it from management console, or run a SQL query. Depending on database engine you are using this might look a little different but the concept is the same.
MYSQL:
In MySQL workbench right click on table in question, select Alter Table and check NNm and AI next to column you want auto increment. See Screenshot
Or run command:
ALTER TABLE `dbName`.`nameOfTheTable` MODIFY `columnName` INT AUTO_INCREMENT NOT NULL;
I am a bit rusty on my SQL, so if it does not work let me know I will get you right command.
Hope this helps. Good luck.
this is my code for updating:
PS: empid is a foreign key but i think that shouldnt be the reason and the code is in CakePHP
if($this->request->is('post'))
{
$this->request->data["Leave"]["empid"] = $this->request->data["id"];
$this->Leave->empid = $this->request->data["Leave"]["empid"];
$this->request->data["Leave"]["leave_start"] = $this->request->data["start_date"];
$this->request->data["Leave"]["leave_end"] = $this->request->data["end_date"];
$this->request->data["Leave"]["leave_taken"] = $this->request->data["leave_taken"];
if($this->Leave->save($this->request->data['Leave']))
{
return $this->redirect(array('action' => 'manage_leave'));
}
}
// This code is inserting a new row instead of updating and also not adding any value in the new row
May be your trying to update the foreign table data using simple save.
Update multiple records for foreign key
Model::updateAll(array $fields, mixed $conditions)
Example
$this->Ticket->updateAll(
array('Ticket.status' => "'closed'"),
array('Ticket.customer_id' => 453)
);
Simple save for the primary key
Make sure that your HTML has empid
echo $this->Form->input('Leave.empid', array('type' => 'hidden'));
Save Model
$this->Leave->empid = $this->request->data["Leave"]["empid"]; //2
$this->Leave->save($this->request->data);
In between, you can also try to set the model data and check the $this->Leave->validates() and $this->Leave->validationError if they are giving any validation errors.
// Create: id isn't set or is null
$this->Recipe->create();
$this->Recipe->save($this->request->data);
// Update: id is set to a numerical value
$this->Recipe->id = 2;
$this->Recipe->save($this->request->data);
You can find more information about all Saving your data
Hope this helps you :)
And in case if $empid is primary key of corresponding table of Leave model (e.g leaves), Just replace:
$this->Leave->empid = $this->request->data["Leave"]["empid"];
By
$this->Leave->id = $this->request->data["Leave"]["empid"];
I am having an issue with updating a MySql table using codeigniter.
Basically, its inserting 'img' the characters, into the table rather than the value of the variable.
This is so strange!
Here is my model:
public function update_course_progress($progress_data) {
$course_id = $progress_data['course_id'];
$user_id = $progress_data['user_id'];
$progress = $progress_data['progress'];
$status = $progress_data['status'];
$update_data = array (
'progress' => $progress,
'status' => $status,
);
// perform update on the matching row
$this->db->update('training_stats', $update_data, array('course_id' => $course_id, 'user_id' => $user_id));
}
So, the issue is with 'progress' instead of inserting the value of this variable it is inserting 'img'???
So, if i var_dump $update_data i get this:
array(2) {
["progress"]=> string(2) "1a"
["status"]=> string(1) "i"
}
Which is correct:
And if i use the profiler in CI to get the db queries, this is what I get:
UPDATE `training_stats`
SET `progress` = '1a', `status` = 'i'
WHERE `course_id` = '8'
AND `user_id` = '2'
Which is correct.
So WHY ON EARTH is it inserting null into the db instead of 1a.
The table structure for this column is VARCHAR(4).
progress varchar(4) NOT NULL DEFAULT '0',
What the hell is going on? why on earth is it img input???
What can be wrong?
UPDATE:
As i was debugging, i tried an insert instead of an update, and 2 rows were inserted. The first row was the expected data, and the second row was the data with 'img' in it. Both rows were the same except for the 'progress' column, which had img inserted in the second row.
So obviously it had been updating the row with the correct data and then overwriting it with the incorrect data.
But now why are there 2 rows being inserted? There is no loop? and why is the CI profiler not logging the second query, if that is indeed what is happening
As of per documentation of CI I will use the more standard method of updating data.
$updateArray = array (
'progress' => $progress_data['progress'],
'status' => $progress_data['status'],
);
$whereArray = array(
'course_id' => $progress_data['course_id'],
'user_id' => $progress_data['user_id']
)
$this->db->set($updateArray);
$this->db->where($whereArray);
$this->db->update('training_stats');
This should do, I also think you shouldn't put extra variables for the data as you did. With such short function you really are not having any benefits sinds all data is only accessed once and seem like unnecessary to me, though opinions could vary.
I have the following code in CakePHP 2:
$this->Order->id = 5;
$this->Order->saveAll(array(
'Order' => array(
'person_id' => $this->Session->read('Person.id'),
'amount' => $total,
'currency_id' => $code
),
'Lineitem' => $lineitems /* a correctly-formatted array */
));
I would expect this to update the row with the Primary Key of 5 in the Order table and then insert the Lineitem rows with an order_id of 5.
However, all it does is create a new row in Order and then use the new id from the new Order record to create the Listitem rows.
Note: I'm only setting the ID as above for debugging purposes and to easily demonstrate this question. In my final code, I'll be checking to see if there's already a pending order with the current person_id and doing $this->Order->id = $var; if there is and $this->Order->create(); if there isn't.
In other words, sometimes I will want it to INSERT (in which case I will issue $this->Order->create(); ) and sometimes I will want it to UPDATE (in which case I will issue $this->Order->id = $var; ). The test case above should produce an UPDATE but it's producing an INSERT instead.
Any idea what I am doing wrong here?
The array you pass to Model->saveAll() doesnt't contain the order's id, so Cake creates a new one. If you wanto to update an existing record, either you set the order id in the passed array, or you retrieve it with a find. The documentation explicitly remarks
If you want to update a value, rather than create a new one, make sure
your are passing the primary key field into the data array
$order = $this->Order->findById(5);
// ... modify $order if needed
$this->Order->saveAll(array('Order' => $order, 'LineItem' => $items));
In your case, you may want to use something like the following to be as concise as possible. Model::saveAssociated() is smart enough to create or update depending on the id, but you must provide suitable input. Model::read($fields, $id) initializes the internal $data: for an existing record all fields will be read from the database, but for a nonexistent id, you'll need to supply the correct data for it to succeed. Assuming an order belongsTo a customer, I supply the customer id if the order doesn't exist
// set the internal Model::$data['Order']
$this->Order->read(null, 5);
// You may want to supply needed information to create
// a new order if it doesn't exist, like the customer
if (! $this->Order->exists()) {
$this->Order->set(array("Customer" => array("id" => $customer_id)));
}
$this->Order->set(array('LineItem' => $items));
$this->Order->saveAssociated();
As a final note, it seems you are implementing a shopping cart. If that's the case, maybe it'd be clearer to use a separate ShoppingCart instead of an Order with a finalized flag.
Have you tried following:
$this->Order->saveAll(array(
'Order' => array(
'id' => 5,
'person_id' => $this->Session->read('Person.id'),
'amount' => $total,
'currency_id' => $code
),
'Lineitem' => $lineitems /* a correctly-formatted array */
));
Its pretty much the same what you did with :
$this->Order->id = 5;
Maybe that would fix your problem.
Cake is checking if you set id field and if its there it updates record, if not found it creates new record instead.
update:
Then maybe check before you saveAll if there is id field, then save result of check to some boolean and create array to save determined by this boolean for example:
if($id_exist) $order['Order']['id'] = 5;
$order['Order']['id'] = 5;
$order['Order']['person_id'] = $this->Session->read('Person.id'),
$order['Order']['amount'] = $total;
$order['Order']['currency_id'] = $code;
$this->Order->saveAll(array(
'Order' => $order,
'Lineitem' => $lineitems /* a correctly-formatted array */
));