Using Gii to create room, customer, and reservation models

Yii2 provides a powerful tool to generate models, controllers, and CRUD (create, read, update, and delete) actions, forms, modules, and extensions: Gii.

At the bottom of the basic/config/web.php file, placed in the basic standard configuration, there is a block of code that enables Gii:

if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = 'yiidebugModule';

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

Verify that these lines are present, otherwise append them at the bottom of the web.php file before the return $config statement. The last check is in basic/web/index.php. Verify that YII_ENV is dev, with this line:

defined('YII_ENV') or define('YII_ENV', 'dev');

Now, we can point our browser to http://hostname/basic/web/gii, and we should see this error page:

Using Gii to create room, customer, and reservation models

Forbidden access to Gii

This page will be displayed since access to Gii is locked by a password.

We need to add extra configuration to the gii module, passing other allowed IPs. Gii's configuration has an attribute named allowedIPs, which consents to specify which IP addresses can access the Gii page:

 'allowedIPs' => ['127.0.0.1', '::1', '192.168.178.20']

In this extract, Gii will accept access from a localhost (in the IPv4 form with 127.0.0.1 and IPv6 form with ::1) and from 192.168.178.20, which should be our IP address in private network.

If the Yii2 application is running on an external hosting, we will set our IP public address in this list of allowed IPs. For example, if our IP is 66.249.64.76, this entry will be appended to existent (if we want maintain other permitted access points):

 'allowedIPs' => ['127.0.0.1', '::1', '192.168.178.20', '66.249.64.76']

To allow access from everywhere (useful in the development stage), we can add * in this list, which means that the Gii page can be accessed from every IP address:

'allowedIPs' => ['127.0.0.1', '::1', '192.168.178.20', '*']

Consequently, the content of gii]['gii'] = 'yiigiiModule' is:

    $config['modules']['gii'] = [
        'class' => 'yiigiiModule',
        'allowedIPs' => ['127.0.0.1', '::1', '192.168.178.20', '*'] ]; configuration in basic/config/web.php will be:
if (YII_ENV_DEV) {
    // configuration adjustments for 'dev' environment
    $config['bootstrap'][] = 'debug';
    $config['modules']['debug'] = 'yiidebugModule';

    $config['bootstrap'][] = 'gii';
    //$config['modules'
}

Now, we are able to access to Gii from any IP.

Refresh the browser by clicking on the page http://hostname/basic/web/gii and we can finally see its content:

Using Gii to create room, customer, and reservation models

Successful access to Gii

Now, click on the Start button of Model Generator; we will have a form of Model Generator where Table Name is the unique field to fill in. When we start to type the table name, auto-suggestion will display the possible choices. After doing this, when we move to the Model Class field, this will be automatically filled in by a framework. The other fields can be left with the default settings.

Type room in Table Name and then click on the Model Class field. This field will be filled with Room, which is the filename in the models folder.

Clicking on the Preview button will display the path where the file will be created and the action will be applied (it should be the overwrite value because we created it in the previous chapter).

Finally, click on the Generate button to complete this action. A response message will give us information about the execution of this operation.

This is the form with a successful result:

Using Gii to create room, customer, and reservation models

Model Generator of Gii

Repeat this operation for the other two tables: reservations and customers.

Now, we have three models in the basic/models folder: Room.php, Reservation.php, and Customer.php.

Let's explain what Gii has done. Open the basic/models/Room.php file, and we have three methods:

  • tableName()
  • rules()
  • attributeLabels()

The first method, tableName(), simply returns the name of table to which this model is linked:

    public static function tableName()
    {
        return 'room';
    }

The second method, rules(), is important because it contains rules validation to be checked when the validate() method is launched (it is launched automatically in the save() method) or a massive attributes assignment as:

$model->attributes = arrayWithData;

This is the content of the rules() method:

    public function rules()
    {
        return [
            [['floor', 'room_number', 'has_conditioner', 'has_tv', 'has_phone', 'available_from'], 'required'],
            [['floor', 'room_number', 'has_conditioner', 'has_tv', 'has_phone'], 'integer'],
            [['available_from'], 'safe'],
            [['price_per_day'], 'number'],
            [['description'], 'string']
        ];
    }

The first rule specifies that the fields floor, room_number, has_condition, has_tv, and avaiable_from are mandatory because they are passed to the required validator. Moreover, they must be an integer, as required by the second rule.

Note

Fields that are not in rules, will be skipped in a massive assignment because they are considered unsafe (since they are not present in rules). So it is necessary that when a field that has not got a validator rule, it must have an entry in the 'safe' validator.

The fourth rule specifies that the price_per_day field is a number, while the last rule states that description is a string.

Note

These rules are read automatically from the database field type and constraint.

The last method attributeLabels() specifies the representation of fields in the display view as a form, grid, and so on.

This is the content of attributeLabels():

    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'floor' => 'Floor',
            'room_number' => 'Room Number',
            'has_conditioner' => 'Has Conditioner',
            'has_tv' => 'Has Tv',
            'has_phone' => 'Has Phone',
            'available_from' => 'Available From',
            'price_per_day' => 'Price Per Day',
            'description' => 'Description',
        ];
    }

Yii2 reports—in the model—any relationship between the tables present in a database. We have the Reservation model that has links to Room and Customer.

Follow these instructions to make the framework able to create a relationship in the model:

  1. Check that the database tables use the InnoDB engine (which supports relationships and foreign keys).
  2. In the Reservation table, add two indexes, respectively for the room_id and customer_id fields:
    ALTER TABLE `reservation` ADD INDEX ( `room_id` ) ;
    ALTER TABLE `reservation` ADD INDEX ( `customer_id` ) ;
  3. In the Reservation table, add two constraints to the room and customer tables:
    ALTER TABLE `reservation` ADD FOREIGN KEY ( `room_id` ) REFERENCES `room` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ;
    ALTER TABLE `reservation` ADD FOREIGN KEY ( `customer_id` ) REFERENCES `customer` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ;

    Note

    In these constraints, we used RESTRICT for DELETE and UPDATE operations. RESTRICT avoids the deletion of reservations that refer to customers or rooms that we are trying to delete. Therefore, to delete a customer or room that figures in reservations, we will be required to first delete the reservations.

    This behavior ensures that important data such as reservations is never deleted automatically (in a cascade) when deleting a room or a customer. An error message will be displayed when you try to do this to a reservation linked to the customer or room.

    In other contexts, a commonly used keyword is CASCADE, which removes all data that refers to linked tables.

Open Gii again and navigate to http://hostname/basic/web/gii, then click on the Start button in Model Generator and type room in Table Name. Click on the Preview button at the bottom of the page and this time you will see that models/Room.php exists and the action is overwrite, unflagged.

Click on the check near 'overwrite' and then on the Generate button. In this way, we have forced to overwrite the Room model with the relational data from the Room table.

Now, basic/models/Room.php contains a new method named getReservations at the bottom, with this content:

    /**
     * @return yiidbActiveQuery
     */
    public function getReservations()
    {
       return $this->hasMany(Reservation::className(), ['room_id' => 'id']);
    }

This method returns an ActiveQuery instance, which is used to build a query to be dispatched to the database.

Note

When called as a property, this method will return the list of reservations linked to the model.

You might encounter the case where $model is an instance of the Room class for example: $reservationsList = $model->reservations;

In this case, fill the $reservationsList variables with a list of reservations related to this Room model.

This is not surprising, although the hasMany method returns an ActiveQuery object.

If we explore the __get() method of BaseActiveRecord (which is the base class of ActiveRecord) that handles the property requirements, we can see these lines of code:

            $value = parent::__get($name);
            if ($value instanceof ActiveQueryInterface) {
                return $this->_related[$name] = $value->findFor($name, $this);
            } else {
                return $value;
            }

This returns linked results when the $value content is an instance of ActiveQueryInterface (which is an interface implemented by the ActiveQuery class).

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

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