I've got an ActiveRecord BaseModel
class and a lot of classes-models which inherit from it. And i've got a class Bookmark
, which is inherited from BaseModel
as well.
Also, i've got Decorator
-inherited classes, they implements special interface to represent single model ( getModelView(model)
method). This is some pseudo-code:
TestModel inherits BaseModel
getName:
return this.name
BookmarkModel inherits BaseModel
BaseModel model
getBookmark:
return this.model
TestDecorator inherits BaseDecorator implements SingleModelViewInterface:
getView(model):
return 'view' //html-view of model
BookmarkDecorator inherits BaseDecorator
getBookmarksView(BookmarkModel[] bookmarks):
foreach(bookmarks > bookmark):
decorator = Relation::getDecoratorByModel(bookmark->getEntityType())
decorator->getView(bookmark->getBookmark())
So, everything looks good, until i want to change that View for bookmarked model a bit. I want a to add a custom title for that view. And i can't make it inside decorator, because it renders it not only for a bookmarks.
EDIT: So, the problem is - seems that i need a decorator pattern, but i dont have anything to inherit from, because concrete TestDecorator using TestModel speical methods. So now i've done some really bad realization, using magic methods (PHP):
class BookmarkedModel {
/** @var BaseEntityModel*/
private $model;
public function __construct(BaseEntityModel $model) {
$this->model = $model;
}
public function getName() {
return 'Bookmark '.$this->model->getName();
}
public function __call($name, $arguments) {
return call_user_func_array(array($this->model, $name), $arguments);
}
public function __get($name) {
return $this->model->$name;
}
public function __set($name, $value) {
return $this->model->$name[$value];
}
}
So it will work for now, but in terms of code structure, readability and stability it's really bad decision.
In software engineering, the active record pattern is considered an architectural pattern by some people and as an anti-pattern by some others recently. It is found in software that stores in-memory object data in relational databases.
ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.
ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code.
The model should be unaware of the view. Models represent the raw data seen from every angle at once. The view is a perspective of that model. The controller should feed the model to the view:
$model_view->render($model);
Then decorate the view:
$bookmark_view->render($model); // bookmark_view wraps a model_view,
// returns 'Bookmark '.$this->model_view->render($model)
Only decorate based on interfaces, not types.
PHP's magic methods are great, but they should not be used for ActiveRecord, this goes against "separation of concerns", in this case separating the model from it's persistence mechanism.
Instead make an ActiveRecord object and feed the model to it.
$record->store($model);
Then if you need to modify storage, again just decorate the storage mechanism:
$log_record->store($model); // wraps $record, logs a message prior to database storage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With