Last active
November 29, 2016 18:24
-
-
Save tom--/b5626e3a999c8aea73b872c3c428281d to your computer and use it in GitHub Desktop.
Conceptual demo of data mapping in a Yii webapp. It's no prototype to elaborate into real software. It's only an object of philosophical contemplation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* A global Persister "static" class isolates the location of any persistence logic from its users. | |
* In this example, persitence logic for UserMovieRating objects is located in this class but it | |
* could be moved around ad hoc. | |
*/ | |
class Persister | |
{ | |
private static function _UserMovieRatingSave(UserMovieRating $object) | |
{ | |
(new Rating([ | |
'userId' => $object->userId, | |
'movieId' => $object->movieId, | |
'stars' => $object->rating, | |
]))->insert(false); | |
} | |
// todo: Methods for finding UserMovieRating models, updating or deleting them, as needed | |
public static function save($object) | |
{ | |
// Locate the save method for the object according to its type. | |
$method = '_' . get_class($object) . 'Save'; | |
self::$method($object); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class RateController extends \yii\base\Controller | |
{ | |
public function actionRate() | |
{ | |
$form = new RateForm(); | |
if ($form->load(\Yii::$app->request->post()) && $form->validate()) { | |
// The controller understands nothing of input mapping (from form model to data object) | |
// except that the form model provides it. | |
$dataObject = $form->getDataObject(Yii::$app->user->identity); | |
// And understands nothing of storage mapping (from data object to persistent storage), | |
// not even where it is. | |
Persister::save($dataObject); | |
return $this->redirect(['somewhere']); | |
} | |
return $this->render('rate', ['model' => $form]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Standard Yii form model except for the addition of methods containing logic | |
* mapping between a form instance and whatever data object(s) it uses. | |
*/ | |
class RateForm extends yii\base\Model | |
{ | |
public function rules() | |
{ | |
// whatever you need. familliar stuff | |
} | |
public function getDataObject(User $user) | |
{ | |
return new UserMovieRating([ | |
'userId' => $user->id, | |
'movieId' => $this->movieId, | |
'rating' => $this->rating, | |
]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Standard AR model without any form or validation stuff. This does nothing except | |
// provide a standard API to the persistent storage data structures. This is not an | |
// abstract API, it reflects e.g. DB schema, so DB migrations may cause rework of | |
// Persister logic. | |
class Rating extends \yii\db\ActiveRecord | |
{ | |
public static function tableName() | |
{ | |
return 'rating'; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* In this example, just data. But it could have logic too. The main point is that this | |
* class is reusable within the app and is isolated from forms and from DB. If either of | |
* those changes, the corresponding changes to mapping logic are isolated elsewhere. | |
*/ | |
class UserMovieRating | |
{ | |
public $userId; | |
public $movieId; | |
public $rating; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The concept of repositories is OK but I'd make it non-static.