A
A
Andrey Ivchenkov2016-03-17 13:33:50
Yii
Andrey Ivchenkov, 2016-03-17 13:33:50

Yii2 best practices. How to properly organize model inheritance?

There is a project on the Yii2 framework with the advanced template. According to the guide, it is recommended to store the general business logic of models in common, and implement specific logic in the corresponding inherited frontend and backend models.
But what about relationships? It turns out that they also need to be redefined? I'll give you an example.
User and order models in common:

namespace app\common\models;


use yii\db\ActiveRecord;

class User extends ActiveRecord{

    public function getOrder(){
        return $this->hasOne(app\common\models\Order::className(), ['user_id' => 'id']);
    }
}

namespace app\common\models;


use yii\db\ActiveRecord;

class Order extends ActiveRecord{

}

In the frontend, we create classes inherited from the corresponding classes from common:
namespace app\frontend\models;


use yii\db\ActiveRecord;

class User extends app\common\models\User{

}

namespace app\frontend\models;

use yii\db\ActiveRecord;

class Order extends app\common\models\Order
{
    public function newMethod()
    {
           //Some logic
    }
}

And we try to do this:
$user = new app\frontend\models\User();
$user->order->newMethod();

Let's catch the exception, because newMethod is only defined in the Order class of the frontend.
What does it get? Do you need to define relationships only in backend and frontend? Why is common needed then?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Makarov, 2016-03-17
@Groonya

The AR class in backend / frontend may not be inherited from the AR class from common if the logic of their use is different, albeit a little similar.
common is needed if everything is the same at the base level, but the part of the business logic embedded directly in the AR class is different.
On a good note, by the way, the business logic should be placed in a separate layer, but since for the sake of two lines you don’t want to sculpt it, as long as there is not enough of it, it remains in AR classes.

M
Mylistryx, 2016-03-17
@Mylistryx

public function getOrder(){
// was
return $this->hasOne(app\common\models\Order::className(), ['user_id' => 'id']);
// became
return $this->hasOne(Order::className(), ['user_id' => 'id']);
}
since they have the same namespace, it will work both in common and in front/back. In this case, it will take the adjacent class.
The only caveat is that the Order file must be present in all applications (common, front, back).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question