Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Appropriate pattern for ActiveRecord class

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.

like image 911
UnstableFractal Avatar asked Apr 29 '13 11:04

UnstableFractal


People also ask

Is ActiveRecord an anti-pattern?

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.

What is ActiveRecord base?

ActiveRecord::Base indicates that the ActiveRecord class or module has a static inner class called Base that you're extending.

Is ActiveRecord an ORM?

ActiveRecord is an ORM. It's a layer of Ruby code that runs between your database and your logic code.


1 Answers

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.
like image 97
y o Avatar answered Oct 16 '22 09:10

y o