Queries
Because
yii\db\ActiveQueryextends fromyii\db\Query, you can use all query building methods and query methods.
A call to yii\db\ActiveRecord::find() always returns an ActiveQuery object.
Get a single record:
$customer = Customer::find()
->where(['id' => 123])
->one();
Get many records:
$customers = Customer::find()
->where(['status' => Customer::STATUS_ACTIVE])
->orderBy('id')
->all();
Relational queries:
$orders = $customer->getOrders()
->where(['>', 'subtotal', 200])
->orderBy('id')
->all();
Using OR operator:
$events_tba_active = Event::find()
->where(['makes_sense' => 1, 'type' => Event::TYPE_WITHOUT_DATE])
->andWhere(['OR', ['<=', 'date', new Expression('CURDATE()')], ["date" => null]])
->orderBy('date ASC')
->all();
Check if a value is null:
$query->andFilterWhere(['is', 'hourly_range', new Expression('null')]);
Another variant of specifying conditions:
Job::deleteAll("created_timestamp < $time_border AND hit != 1");
More complex example:
// DELETE FROM job WHERE publication_timestamp < $time_border AND (starred = 0 OR (starred = 1 AND viewed = 1) )
return Job::deleteAll(
['AND', ['<', 'publication_timestamp', $time_border], ['OR', ['starred' => 0], ['starred' => 1, 'viewed' => 1]]]
);
Comparison operators are given as the first element of the condition array:
$records = Record::find()
->where(['>=', 'row_index', $range_from])
->limit($amount)
->all();
Lazy and eager loading
Lazy loading means related data is fetched on demand. The code below runs an extra query per post:
<p>Category: <?= $post->category->name ?></p>
Eager loading fetches the related records together with the primary ones:
$posts = Post::find()->with('category')->all();
Dynamic relational queries
Worth remembering:
$customer->getOrders(); // returns an ActiveQuery
$customer->orders; // returns ActiveRecord objects
Because the getter returns a query, the relation can be refined before execution:
$orders = $customer->getOrders()
->where(['>', 'subtotal', 200])
->orderBy('id')
->all();
Events
Hook into the record lifecycle by overriding the corresponding methods. Always call the parent implementation and respect its result:
public function beforeSave($insert)
{
if (!parent::beforeSave($insert)) {
return false;
}
// Actions...
return true;
}
public function beforeDelete()
{
if (!parent::beforeDelete()) {
return false;
}
// Actions...
return true;
}
Inside these methods you can tell an insert from an update:
if ($this->getIsNewRecord()) {
// ...
}
Andrew Dorokhov