Common Models Usage In Advanced App

For example we have 3 models:

[list=1]

[*]common\models\User

[*]backend\models\User - extended from common\models\User

[*]frontend\models\User - extended from common\models\User

[/list]

Common model contains:

[list=1]

[*]PHPDoc comment about all used attributes (for IDE autocomplete from both backend and frontend models)

[*]Table name (if it’s different from the standard convention)

[*]Common properties and methods for both backend and frontend models (if they exist)

[/list]

The frontend and backend logic is isolated in corresponding models.

For example, if only administrator can create records, the backend model contains rules, validators, etc.

The frontend model contains all logic which is responsible for interacting with users of the site.

This concept is flexible, but I don’t understand how to better deal with relations and queries.

  1. Let’s say we have relation cities and it’s used across all site.

The first solution that comes to mind is declare the relation in common model. This helps avoid duplicating code.

But if the method will return array of models with class common\models\City, when we call the relation from frontend or backend, the frontend and backend specific methods of City model will become inaccessible because they simply don’t exist there.

The only workaround I found it’s just duplicating code of the relations with different namespace. In frontend the method should return array of frontend\models\City, in backend - array of backend\models\City.

That works, but I’m pretty sure that it’s not the best solution.

  1. As I understand when using this concept it’s not right to use common model in frontend or backend app, so we should always use namespace frontend\models\User and backend\models\User.

If we have the same functionality for frontend and backend, is it OK to use just one common model?

And what if we have common and backend models, and frontend is the same as common. Should we create the empty frontend model to follow convention or just use common model in frontend?

Creating separate frontend model will be also good for future adding methods to this model (otherwise we need to change namespaces across all project, but it’s not a big problem), but generates extra inheritance.

  1. What if we have common component that used in both frontend and backend app, and it uses relations. We should use common model and declare relations there, and override them in frontend and backend apps only if needed, right?

  2. How to deal with queries? The same as models? Creating common query, extended frontend and backend queries if needed, overriding find() method in each class?

Seems to violate DRY. The controllers/ CRUD views for both frontend and backend can all reference common\models\User via use statement. One authoritative user model would probably be easier to work with and less confusing.

Thanks for your reply.

Sometimes it seems to be better to store everything in just one common model.

Accessing the model in that case is definetely easier.

You can separate the frontend and backend parts by some comment lines but in my opinion it’s not good idea.

But with more complex logic the file can reach big size and became less readable and maintainable.

So in that case splitting to different files seems to be logical solution.

So copying just small amount of code (for example relations with different namespaces) is propably better.

It will be interesting to read others opinions too.

How you deal with that in your projects?

Which logic are you trying to separate for backend/frontend User model?

I try to separate application logic.

That means backend model contains only backend logic, frontend - frontend logic, common - common logic (that is used by both frontend and backend applications).

Which kind of logic it is?

Only related with User model (rules, validators, relations and other methods that are usually used in any model).

Why these are different in these two cases then?

@sam If use in backend/models/model


var_dump($model,$model->relationName) 

then returns backend/models/model and backend/models/relationName because relationName is exists in backend/models/ namespace.

if use in backend/controllers/ModelController


var_dump($model,$model->relationName) 

then returns backend/models/model and common/models/relationName because relationName isnt exists in

backend/controllers namespace

use namespace ‘app’ for these Models in both application

when you call it, bring the right one

;)