Im having some problems with my unittest.
My unittest works perfect if the test is about to get anything from my datbase table.
But if I should create example a customer, im having isuses with how I should do that.
Here is an example of my getCustomer test:
Try something like this:
<?php
$controller = new Veosoft_Controller();
$_REQUEST = [
'displayName' => 'meh',
'firstname' => 'Kristian',
'lastname' => 'Pedersen',
];
$controller->createCustomer();
// then somehow get the last insert ID?
$customer = $controller->getSpecificCustomer($customerId);
$this->assertEquals($customer->id, $customerId);
$this->assertEquals($customer->firstname, $firstName);
$this->assertEquals($customer->lastname, $lastName);
Of course it would be better if you just mocked the DB class itself?
Related
I'm using Codeigniter 4.
And inserting new data like this,
$data = [
'username' => 'darth',
'email' => 'd.vader#theempire.com'
];
$userModel->save($data);
Which is mentioned here: CodeIgniter’s Model reference
It's doing the insertion.
But I haven't found any reference about to get the inserted id after insertion.
Please help! Thanks in advance.
This also works.
$user= new UserModel();
$data = [
'username' => 'darth',
'email' => 'd.vader#theempire.com'
];
$user->insert($data);
$user_id = $user->getInsertID();
I got a simple solution after researching on the core of the CI 4 framework.
$db = db_connect('default');
$builder = $db->table('myTable');
$data = [
'username' => 'darth',
'email' => 'd.vader#theempire.com'
];
$builder->insert($data);
echo $db->insertID();
Hope they'll add a clear description on the docs soon.
There are three way to get the ID in ci4:
$db = \Config\Database::connect();
$workModel = model('App\Models\WorkModel', true, $db);
$id = $workModel->insert($data);
echo $id;
echo '<br/>';
echo $workModel->insertID();
echo '<br/>';
echo $db->insertID();
In fact, what you did is correct.
You did it in the best and easiest way and following the Codeigniter 4 Model usage guide.
You just missed: $id = $userModel->insertID;
Complete code using your example:
$data = [
'username' => 'darth',
'email' => 'd.vader#theempire.com'
];
$userModel->save($data);
$id = $userModel->insertID;
That's it. You don't need all this code from the examples above nor calling database service or db builder if you're using codeigniter's models.
Tested on CodeIgniter 4.1.1 on 3/19/2021
To overcome this, I modified system/Model.php in the save() method---
$response = $this->insert($data, false);
// add after the insert() call
$this->primaryKey = $this->db->insertID();
Now, in your models, you can just reference "$this->primaryKey" and it will give you the needed info, while maintaining the data modeling functionality.
I'm going to submit this over to the CI developers, hopefully it will be added in.
For CI4
$settings = new SettingsModel();
$settingsData = $settings->find(1);
<?php namespace App\Models;
use App\Models\BaseModel;
class SettingsModel extends BaseModel
{
protected $table = 'users';
protected $primaryKey = 'id';
}
$settings->find(1); will return a single row. it will find the value provided as the $primaryKey.
hi guys in my case i use ci model to save data and my code is :
$x=new X();
$is_insert= $x->save(['name'=>'test','type'=>'ss']);
if($is_insert)
$inserted_id=$x->getInsertID()
I'm using mysql for my database then I ran this inside my seeder
$university = $this->db->table('universities')->insert([
'name' => 'Harvard University'
]);
$faculty = $this->db->table('faculties')->insert([
'name' => 'Arts & Sciences',
'university' => $university->resultID
]);
Look at code line 6
$university->resultID
variable $university here is type object of CodeIgniter\Database\MySQLi\Result class
Corect me if I'm wrong or any room for improvements
I had the same problem but, unfortunately, the CI4 documentation doesn't help much. The solution using a builder woks, but it's a workaround the data modeling. I believe you want a pure model solution, otherwise you wouldn't be asking.
$data = [
'username' => 'darth',
'email' => 'd.vader#theempire.com'
];
$id = $userModel->save($data);
Trying everything I could think of I decided to store the result of the save method to see if returned a boolean value to indicate if the saving was sucessful. Inspecting the variable I realized it returns exactly what I wanted: the lost insertID.
I believe CodeIgniter 4 is quite an easy and capable framework that does a decent job in shared hosts where other frameworks can be a little demanding if you're learning but lacks the same fantastic documentation and examples of CI3. Hopefully, that's only temporary.
By the way, you code works only if you are using the $userModel outside the model itself, for example, from a Controller. You need to create a model object like:
$userModel = New WhateverNameModel();
$data = [any data];
$userModel->save($data);
Alternatively, if you are programming a method inside the model itself (my favorite way), you should write
$this->save($data);
I'm doing this:
$students = Student::find()->all();
return $this->render('process', array('students' => $students));
and then this in the view:
foreach($students as $student)
{
echo $student->name . ', ';
echo $student->getQuizActivitiesCount(); ?> <br /> <?php
}
i would like to see the sql query being performed. a student "has many" quiz activities, and the query performs perfectly, but i need to see the raw SQL. is this possible?
Method 1
With relations that return yii\db\ActiveQuery instance it's possible to extract the raw SQL query directly in code for example with var_dump().
For example if we have user relation:
/**
* #return \yii\db\ActiveQuery
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
You can then var_dump() the raw SQL like that:
var_dump($model->getUser()->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
exit();
Note that you should call it like that and not $model->user->... (the latter returns User instance).
But in your case it's not possible because count() immediately returns int. You can var_dump() partial query without count(), but I think it's not convenient.
Note that you can use this method for dumping generated SQL of any ActiveQuery instances (not only those that were returned by relation), for example:
$query = User::find()->where(['status' => User::STATUS_ACTIVE]);
var_dump($query->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
exit();
Method 2
This is much simpler in my opinion and I personally prefer this one when debugging SQL queries.
Yii 2 has built-in debug module. Just add this to your config:
'modules' => [
'debug' => [
'class' => 'yii\debug\Module',
],
],
Make sure you only have it locally and not on production. If needed, also change allowedIPs property.
This gives you functional panel at the bottom of the page. Find the DB word and click on either count or time. On this page you can view all executed queries and filter them.
I usually don't filter them in Grid and use standard browser search to quickly navigate through and find the necessary query (using the table name as keyword for example).
Method 3
Just make an error in query, for example in column name - cityy instead of city. This will result as database exception and then you can instantly see the generated query in error message.
If you want to log all relational queries of ActiveRecord in console application all proposed methods don't help. They show only main SQL on active record's table, \yii\debug\Module works only in browser.
Alternative method to get all executed SQL queries is to log them by adding specific FileTarget to configuration:
'log' => [
'targets' => [[
...
], [
'class' => 'yii\log\FileTarget',
'logFile' => '#runtime/logs/profile.log',
'logVars' => [],
'levels' => ['profile'],
'categories' => ['yii\db\Command::query'],
'prefix' => function($message) {
return '';
}
]]
]
UPDATE
In order to log insert/update/delete queries one should also add yii\db\Command::execute category:
'categories' => ['yii\db\Command::query', 'yii\db\Command::execute']
you can try this, assume you have a query given like:
$query = new Books::find()->where('author=2');
echo $query->createCommand()->sql;
or to get the SQL with all parameters included try:
$query->createCommand()->getRawSql()
In addition to arogachev answer, when you already work with an ActiveQuery object, here is the line I search to view the rawsql.
/* #var $studentQuery ActiveQuery */
$studentQuery = Student::Find();
// Construct the query as you want it
$studentQuery->where("status=3")->orderBy("grade ASC");
// Get the rawsql
var_dump($studentQuery->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql);
// Run the query
$studentQuery->all();
when you have a query object you can also use
$query->createCommand()->getRawSql()
to return the Raw SQL with the parameters included or
$query->createCommand()->sql
which will output the Sql with parameters separately.
In order to log/track every/all queries:
extend \yii\db\Connection and override createCommand method, like below:
namespace app\base;
class Connection extends \yii\db\Connection {
public function createCommand($sql = null, $params = array()) {
$createCommand = parent::createCommand($sql, $params);
$rawSql = $createCommand->getRawSql();
// ########### $rawSql -> LOG IT / OR DO ANYTHING YOU WANT WITH IT
return $createCommand;
}
}
Then, simply change your db connection in your db config like below:
'db' => [
'class' => 'app\base\Connection', // #### HERE
'dsn' => 'pgsql:host=localhost;dbname=dbname',
'username' => 'uname',
'password' => 'pwd',
'charset' => 'utf8',
],
Now, you can track/read/... all queries executed by db connection.
Try like,
$query = Yii::$app->db->createCommand()
->update('table_name', ['title' => 'MyTitle'],['id' => '1']);
var_dump($query->getRawSql()); die();
$query->execute();
Output:
string 'UPDATE `table_name`
SET `title`='MyTitle' WHERE `id`='1'
' (length=204)
With CI, I want to insert one record in User table and one in Post table. Below is a brief of my code (two tables will have multiple columns, and I just use one as example).
$this->username=$user;
$this->db->insert('User',$this);
$this->title='my first post';
$this->db->insert('Post', $this);
However, the second insert will be something like "insert into Post (user, title) values ('$user', 'my first post'). And an error is reported that unknown column user in Post.
How can I clear the members in $this before inserting the next records (in another table)?
This happening becouse of
$this->username=$user;
You probably need to use
$this->db->insert('Post', $this->title);
And before you insert, set in title anything you want, but not
$this->db->insert('Post', $this);
However if you still want to work with an object, more information how to do this properly you can find here, http://ellislab.com/codeigniter/user-guide/database/active_record.html#insert
CI used array as the second argument in the insert method. The index will be the column name and the value referred by the index will be the value to be inserted. What you did was you just keep adding into the $this array.
When you first add username the array will look like this(neglecting the db) inside $this :
array( 'username' => $user );
When you add the title, it will become like this:
array( 'username' => $user, 'title' => 'my first post');
See how the previous entry still in there.
You can just unset($this->username);
or you can use another variable to hold your data instead of $this. Example:
$data = array('username' => $user);
$this->db->insert('User',$data);
$data = array('title' => 'my first post');
$this->db->insert('Post',$data);
And you can insert into two columns like this:
$data = array('username' => $user, 'description' => 'i am sleepy');
$this->db->insert('User',$data);
Hope my answer can help you.
I have a small piece of code inside a function buts it's not working, even when I pull it out and try it on its own it still doesn't work. I used a MySQL Database Class https://github.com/ajillion/PHP-MySQLi-Database-Class
require_once('class.mysql.php');
$_db = new Mysqlidb('localhost', 'root', '', 'database');
$userCredentials = array(
'userID' => 'asdasda',
'username' => 'dsdasdasd',
'password' => 'v423423c342c23',
'email' => '2423v423#gmail.com',
'userType' => 1,
);
if($_db->insert('users', $userCredentials)) echo 'success';
The correct data is inserted into the database but Success is not displayed, is their a reason for this?
Mysqlidb::insert is wrong. It's return $stmt->insert_id instead of $stmt->execute();. Your query does not use autoincrement value, so, you are getting 0.
Tip from comments:
do not use this library
You got an extra coma at the end of the array you passing as a parameter, I don't think its the problem but still...
Have you tryed to see what is really returned via var_dump?
I'm starting out using the Zend Framework and have created a suitable model which saves data back to a database table. The issue I am having is that the sql statement is trying to insert '?' as the value for each column in the database. I have created the following save function which passes an array of data to the DBtable adapter functions:
public function save() {
$data = $this->getData();
if ($data['pageId']==0) {
$this->getDbTable()->insert($data);
} else {
$this->getDbTable()->update($data, array('pageId = ?' => $data['pageId']));
}
}
This seems to go through the appropriate motions but the item is not added to the database and the sql statement within MySql logs looks something like:
insert into DB_Table ('pageId','title','body') values ('?', '?', '?');
Not quite sure where this is falling down, any pointers would be gratefully received.
Thanks
Data should be in next format:
$data = array(
'pageId' => 1,
'title' => 'title',
'body' => 'body'
);
Are you sure that $this->getDbTable() returns your db adapter?
Try to use:
$db = new Zend_Db_Table('table_name');
$db->insert($data);