Answer the question
In order to leave comments, you need to log in
How to implement a one-time sql query when using Behaivors in a model?
I am implementing a module for unique prices, for this I decided to use the priceAttributeBehavior
attribute in the model .
The logic is simple: a list of individual prices (UniqueService) by user ID is obtained, and it is compared with the ID of the current service, if there is one in the collection - the standard price is replaced by an individual one.
The problem is that in this way, when checking each service, the same SQL query with individual prices is called each time. From thoughts only to use caching, but this is some kind of crutch.
PS It is also interesting how it is possible to implement disabling the call of this behavior, for example it will be useful in the admin panel, and if the user is not authorized. With the first option from the ideas for now, inherit the modelService
and define the behavior with unique prices in the child class, and call it in the right places, and on the second, make a check in the body getValue()
for isGuest()
.
UniqueService, fields: id, user_id, service_id, price.
Behaivors in the Service model:
public function behaviors()
{
return [
[
'class' => IndividualServicePriceBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_AFTER_FIND => 'price',
],
'priceAttribute' => 'price',
'idAttribute' => 'id',
'individualPrices' => UniqueService::find()->where(['user_id' => Yii::$app->user->id])->all(),
],
];
}
namespace common\behaviors;
use yii\behaviors\AttributeBehavior;
class IndividualServicePriceBehavior extends AttributeBehavior
{
/**
* @var \common\models\UniqueService
*/
public $individualPrices;
public $priceAttribute;
public $idAttribute;
public function getValue($event)
{
foreach ($this->individualPrices as $individualPrice) {
if($individualPrice['service_id'] == $this->owner->{$this->idAttribute}) {
return $this->owner->{$this->priceAttribute} = $individualPrice['price'];
}
}
return $this->owner->{$this->priceAttribute};
}
}
Answer the question
In order to leave comments, you need to log in
to disable any behavior, you can call
To do this, you must specify the behavior with the name
public function behaviors()
{
return [
'behaviorName'=> [
'class' => IndividualServicePriceBehavior::className(),
/// ,,,
],
];
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question