Reputation: 772
I want to add record to a table with ActiveRecord
.
Here is my code:
$model = new Article();
$model->title = 'test title';
$model->content = 'test content';
$model->category_id = 1;
$model->author_id = 1;
if ($model->validate()) {
$model->save();
}
$model->validate()
returns true
, but $model->save()
returns false
.
How to find generated raw sql of $model->save()
?
Meanwhile:
$model->save()->rawSql
is null
and $model->getErrors()
returns empty array.
In debug, all queries are logged, but I did not find any insert or update query.
Upvotes: 7
Views: 11360
Reputation: 4225
This code won't show you exactly the raw sql but you'll get the query pre binding and the params
try {
// this will simulate $model->save();
$builder = $model->getCommandBuilder();
$table = $model->getTableSchema();
$command = $builder->createInsertCommand($table, $model->getAttributes());
$command->_connection->enableParamLogging = true;
$command->execute();
} catch (Exception $e) {
// getText() will print the query with the binding params
// getAttributes() will give you the attributes injected
var_dump($command->getText());
var_dump($model->getAttributes());
die();
}
The result will look like:
"INSERT INTO `fruit` (`order`, `name`, `season`) VALUES (:yp0, :yp1,:yp2)"
array(2) {
["order"] => int(1),
["name"] => null,
["season"] => null
}
Upvotes: 1
Reputation: 33548
$model->save()->rawSql
call can not return null
, it must throw an exception that you are trying to access property of non-object. $model->save()
returns boolean
value - either query executed successfully or not.
If $model->getErrors()
returns empty array and query was not executed at all I'm pretty sure that something is wrong with model event handlers, especially beforeSave()
, check it, it should not return false
. Also check attached behaviors event handlers.
As for getting query. It's useless if it simply was not executed, but if it was, here are some ways to achieve it:
1) Probably the best way. Use debug panel. I also mentioned it here.
2) Look at logs as @robsch adviced.
You can't directly get raw SQL in code with $model->save()
, It will call either insert()
or update()
. If you are interested, here is the part of code for insertInternal()
:
$values = $this->getDirtyAttributes($attributes);
if (empty($values)) {
foreach ($this->getPrimaryKey(true) as $key => $value) {
$values[$key] = $value;
}
}
$db = static::getDb();
$command = $db->createCommand()->insert($this->tableName(), $values);
if (!$command->execute()) {
return false;
}
If you call $command->rawSql
you will get raw sql but you can't do that outside because the command is formed internally.
P.S. This piece of code:
if ($model->validate()) {
$model->save();
}
doesn't make sense because $model->save()
will call $model->validate()
internally.
Upvotes: 5