Download the PHP package yii2tech/ar-role without Composer
On this page you can find all versions of the php package yii2tech/ar-role. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package ar-role
ActiveRecord Role Inheritance Extension for Yii2
This extension provides support for ActiveRecord relation role (table inheritance) composition.
For license information check the LICENSE-file.
Installation
The preferred way to install this extension is through composer.
Either run
or add
to the require section of your composer.json.
Usage
This extension provides support for ActiveRecord relation role composition, which is also known as table inheritance.
For example: assume we have a database for the University. There are students studying in the University and there are instructors teaching the students. Student has a study group and scholarship information, while instructor has a rank and salary. However, both student and instructor have name, address, phone number and so on. Thus we can split their data in the three different tables:
- 'Human' - stores common data
- 'Student' - stores student special data and reference to the 'Human' record
- 'Instructor' - stores instructor special data and reference to the 'Human' record
DDL for such solution may look like following:
This extension introduces [[\yii2tech\ar\role\RoleBehavior]] ActiveRecord behavior, which allows role relation based ActiveRecord inheritance. In oder to make it work, first of all, you should create an ActiveRecord class for the base table, in our example it will be 'Human':
Then you will be able to compose ActiveRecord classes, which implements role-based inheritance using [[\yii2tech\ar\role\RoleBehavior]]. There are 2 different ways for such classes composition:
- Master role inheritance
- Slave role inheritance
Master role inheritance
This approach assumes role ActiveRecord class be descendant of the base role class:
The main benefit of this approach is that role class directly inherits all methods, validation and other logic from the base one. However, you'll need to declare an extra ActiveRecord class, which corresponds the role table. Yet another problem is that you'll need to separate 'Student' records from 'Instructor' ones for the search process. Without following code, it will return all 'Human' records, both 'Student' and 'Instructor':
The solution for this could be introduction of special column 'role' in the 'Human' table and usage of the default scope:
This approach should be chosen in case most functionality depends on the 'Human' attributes.
Slave role inheritance
This approach assumes role ActiveRecord does not extends the base one, but relates to it:
This approach does not require extra ActiveRecord class for functioning and it does not need default scope specification.
It does not directly inherit logic declared in the base ActiveRecord, however any custom method declared in the related
class will be available via magic method __call()
mechanism. Thus if class Human
has method sayHello()
, you are
able to invoke it through Instructor
instance.
This approach should be chosen in case most functionality depends on the 'Instructor' attributes.
Accessing role attributes
After being attached [[\yii2tech\ar\role\RoleBehavior]] provides access to the properties of the model bound by relation, which is specified via [[\yii2tech\ar\role\RoleBehavior::roleRelation]], as they were the main one:
If the related model does not exist, for example, in case of new record, it will be automatically instantiated:
Accessing role methods
Any non-static method declared in the model related via [[\yii2tech\ar\role\RoleBehavior::roleRelation]] can be accessed from the owner model:
This feature allows to inherit logic from the base role model in case of using 'slave' behavior setup approach. However, this works both for the 'master' and 'slave' role approaches.
Validation
Each time the main model is validated the related role model will be validated as well and its errors will be attached to the main model:
You may as well specify validation rules for the related model attributes as they belong to the main model:
Saving role data
When main model is saved the related role model will be saved as well:
When main model is deleted related role model will be delete as well:
Querying role records
[[\yii2tech\ar\role\RoleBehavior]] works through relations. Thus, in order to make role attributes feature work,
it will perform an extra query to retrieve the role slave or master model, which may produce performance impact
in case you are working with several models. In order to reduce number of queries you may use with()
on the
role relation:
You may apply 'with' for the role relation as default scope for the ActiveRecord query:
Tip: you may name slave table primary key same as master one: use 'id' instead of 'humanId' for it. In this case conditions based on primary key will be always the same. However, this trick may cause extra troubles in case you are using joins for role relations at some point.
If you need to specify search condition based on fields from both entities and you are using relational database,
you can use joinWith()
method:
Tip: using
joinWith()
will still require an extra SQL query to retrieve relational data. You can use yii2tech/ar-eagerjoin extension to remove this extra query.
Creating role setup web interface
Figuratively speaking, [[\yii2tech\ar\role\RoleBehavior]] merges 2 ActiveRecords into a single one. This means you don't need anything special, while creating web interface for their editing. You may use standard CRUD controller:
While creating a web form you may use attributes from related role model as they belong to the main one:
For the best integration you may as well merge labels and hints of the related model:
Heads up! In order to work in this simple way you should declare validation rules for the role model attributes being 'safe' in the main one:
Otherwise you'll have to load data for the role model separately:
You should use the role model for its inputs while creating form as well: