On our previous blog post on phabric series 2 we saw how we could already set up a Symfony2 project that can capitalize on the advantages provided by phabric within a Symfony2 behat environment.
This time we are going to see a bit about how to work with Phabric. Working a bit more with the settings of Phabric we realize that it supports a lot of things but it does not support read of previously inserted values. At least currently it does not support that now, hopefully it will soon. Phabric’s work is to insert some data and work with it. This is call mapping of data in Phabric. Phabric maps data to a Phabric space where information is tracked. The main object is called Phabric bus from which all operations are performed and all Phabric entities are derived. Notice that Phabric entities are not Symfony2 entities. They have different roles although for configuration it sounds like they correlate one to one sometimes. For all we have said, if we consider existing data mapping in Phabric we realize read is not implemented in the adapter. There was a proposal to subclass the adapter, however we have not gone into it yet.
Persisting Relational Data
While persisting relational data, the important concept is that usually we always persist one main entity/table from which all other tables are but child tables that are related to the main parent table. In Phabric it is always best to think in terms of the main parent table while configuring things. This is important because as long as we get right the configuration for this main table, all the other configuration will follow without problems.
For instance let’s take a look at the main configuration for a main entity `class` and a derived entity `student`. We usually have an entity class with a related column for that table giving the name of the class. However there are some instances where there will be no class name to be set depending on the specifications. In that case we set the `nameCol` to `NULL`. The related entity is `student` and for that we require a transformation to get the `id` of the related object on the derived table (notice the STUDENTLOOKUP closure defined later).
'class' => array ( 'tableName' => 'class', 'primaryKey' => 'id', 'nameCol' => NULL, 'nameTransformations' => array ( 'Class Start' => 'class_start', 'Student' => 'student_id', ), 'dataTransformations' => array ( 'student_id' => 'STUDENTLOOKUP', ), ), |
After we are done with the main configuration we can proceed to fill the other configuration for student entity which is much simpler. On the Gherkin side, the scenario would provide the `student` table first and then the main table for `class`. It is important to have both of these tables and in that order because of the Phabric mapping.
Background: ... And The following student exists | Student Name | Student Grade | | John Smith | F | And The following class exists | Student | Class Start | | John Smith | Summer 2011 | ... @insulated @passing Scenario: Do something else Then ... |
You can see above that the Student column on the parent table below needs to be mapped to student_id, then searched with that name, now turned into an id, across the child table and its value returned. This thing happens whenever there is such a relationship between tables. This operation must be achieved with a data transformation closure as follows:
$this->phabric->addDataTransformation( 'STUDENTLOOKUP', function($studentName, $bus) { $ent = $bus->getEntity('student'); $id = $ent->getNamedItemId($studentName); return $id; } ); |
We have used a behat background block since this sets up the scenario background common for our set of scenarios for that feature. And finally don’t forget to use the insert operation within the step definition on the Feature Context for the entity we have inserted above:
$this->phabric->insertFromTable('class', $table); |
I would like to thank my friend Marco Pivetta for his patient guidance and brainstorming.
If this has helped you, please consider donating.
Hi Cordoval,
Firstly thanks for taking the time to get Phabric up and running. Your feedback is invaluable as I’m very close to the project I don’t pick up on all the weaknesses or areas for improvement.
I agree with you that Phabric needs to support reading data that hasn’t been inserted via Phabric. Also it’s important to allow updating data not originally inserted via Phabric. I aim to add support for both these elements after developing the ability to reset the database to a known state after each scenario. A tricky task to do economically cross database platform.
I have a number of speaking engagements coming up and am busy preparing for them. Soon after this I expect development on Phabric to proceed at a much faster pace! Stay tuned!
Thanks again,
Ben
Thanks Ben,
I was using doctrine remove or delete functions to clean up particular entities or all of them, for my setup and using behat background or before hooks to do this, so perhaps you are talking about more specific cleaning of data from within phabric?
Anyway, i will look forward next week or so to join you in development.
Encouragements in all good, and come back and drop a reference to your slides and video or more if you have of the talks
thanks!