Sharing ActiveRecord models among applications

Although every folder in the main Yii project could be considered a Yii standalone application, with its own controllers, models, views, and so on, it is conventionally accepted that all shared data are located in the common folder.

So every shared model (such as User, Room, Reservation, and Customer) that could be used in other Yii applications, should be inserted in common/models, under the commonmodels namespace.

From my point of view, when an application needs to use an ActiveRecord from common/models, I rather prefer to point to an extended version in its namespace, so as to have a chance again to add custom methods or properties to model for that application.

For example, consider we have the Room model in common/models:

<?php
namespace commonmodels;
class Room extends ActiveRecord
{
….
….
}

In the backend application, we will create an empty extension to the Room class from common namespace:

<?php
namespace backendmodels;
class Room extends commonmodelsRoom
{
}

In this way, we have the possibility to add custom methods or properties to that specific application (namespace), if needed.

Therefore, every controller, view, or model in backend namespace will point to ackendmodelsRoom, when it needs to refer to the Room ActiveRecord.

Example – displaying available rooms in the frontend site

This example will emphasize the few differences between basic and advanced applications occurring in the developing phase.

The first thing to do is to check whether the database configuration is right, since we have just initialized an advanced application.

Note

The database configuration on the production server can be found in common/config/main.php, whereas the database configuration on the developing server is located in common/config/main-local.php, which overwrites the configuration in common/config/main.php.

Open common/config/main.php and add the db property to the configuration array:

        'db' => [
            'class' => 'yiidbConnection',
            'dsn' => 'mysql:host=localhost;dbname=yii_db',
            'username' => 'my_username',
            'password' => 'my_password',
            'charset' => 'utf8',   
        ],

Change the database properties (host, username, and password) according to our configuration parameters.

Note

Remember to comment out the database configuration in common/config/main-local.php to avoid overwriting configurations.

In this way, we will have complete access to the database and tables previously created, and to rooms' data, indeed.

Now, we are ready to create:

  1. The Room model.
  2. The Rooms controller.
  3. View of index action of the Rooms controller.

The first step requires the use of Gii. By default, Gii is enabled with basic configuration in the frontend application (only from localhost).

We will overwrite this configuration so as to use Gii from everywhere. Therefore, in the frontend local configuration (frontend/config/main-local.php), which has the following lines:

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = 'yiigiiModule';

Replace them with these ones:

    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = [
            'class' => 'yiigiiModule',
            'allowedIPs' => ['*']
    ];    

Now, we can finally access Gii from everywhere. Using the browser, go to http://hostname/yiiadv/frontend/web/gii; a welcome page should be displayed.

Go to Model Generator and fill the first field, Table Name, with room, the name of model we are creating, just as we have done in the previous chapters.

Since, we are working with the advanced template, model files (like other objects created by Gii) will be created in the frontend namespace, or rather in frontend/models.

Therefore, it is necessary to change the first field of Model Generator, Namespace, so as to switch from app/models to common/models, the shared area of common data:

Example – displaying available rooms in the frontend site

Gii model generator in advanced template

In common/models, there should be a Room.php file containing the model of the Room table.

The second step it is to create the controller and the action of the controller to display the rooms list.

Let's create the controller under frontend/controllers/RoomsController.php with the following content:

<?php
namespace frontendcontrollers;

use Yii;
use yiiwebController;
use yiidataActiveDataProvider;
use commonmodelsRoom;

class RoomsController extends Controller
{
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => Room::find(),
            'pagination' => [
                'pageSize' => 20,
            ],
        ]);
        
        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);
    }
}

Make sure that the namespace declaration on top is frontendcontrollers, since every application in the web project has its own namespace (in this case, frontend).

Note

We should never directly subclass yiiwebController, instead we should create a custom controller for each application, for example, frontendcontrollersBaseController, and then subclass it from every controller that we will create in frontendcontrollers.

Finally, the third step is to create view content of index action in frontend/views/rooms/index.php:

<div class="row">
<?php foreach($dataProvider->getModels() as $model) { ?>
    <div class="col-md-3" style="border:1px solid gray; margin-right:10px; padding:20px;">
        <h2>Room #<?= $model->id ?></h2>
        Floor: <?= $model->floor ?>
        <br />
        Number: <?= $model->room_number; ?>
    </div>
<?php } ?>
</div>

This will produce the following output with the data available in the database:

Example – displaying available rooms in the frontend site

Rooms availability in the frontend

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.29.145