John Smith
John Smith

Reputation: 6207

How would you organize a code which operates on two models?

Let's say a new Article is being created and it also has to be Logged, so:

INSERT INTO article VALUES ($name);
INSERT INTO logs VALUES ($name, GET_LAST_ID());

in code:

class Article
{
    public function add($name)
    {
        Sql::exec('INSERT INTO article VALUES ('.$name.')');
    }
}

class Log
{
    public function add($name)
    {
        Sql::exec('INSERT INTO logs VALUES ('.$name.', GET_LAST_ID());
    }
}

in controller:

$article->add('s');
$log->add('s');

of course (apart from SQL hijacks) it's bad, it can anytime be repeated, so COPY+PASTE would it be. How would you organize to a new class? It should be AddArticleAndLogIt ? Certainly not.

Upvotes: 0

Views: 38

Answers (2)

Parziphal
Parziphal

Reputation: 6902

I think it's pretty hard to have a correct answer to this question, because it depends on your preferences (e.g. you don't like observers/triggers) and your code in general. A data-inserter service would be a good choice too, something like:

class DataPersister
{
    public function create($table, array $data)
    {
        // This of course is a very bad implementation, I would
        // use placeholders, but it follows the example code you posted.
        Sql::exec(sprintf(
            'INSERT INTO %s (%s) VALUES (%s)',
            $table,
            implode(', ', array_keys($data)),
            '"' . implode('", "', $data) . '"'
        ));

        $this->log($data);
    }

    public function log(array $data)
    {
        Sql::exec('INSERT INTO logs VALUES (' . $data['name'] . ', GET_LAST_ID());
    }
}

You would use this as:

$articleData = [ 'name' => 's' ];
$persister->create('articles', $articleData);

$commentData = [ ... ];
$persister->create('comments', $commentData);

Upvotes: 1

featherbits
featherbits

Reputation: 862

I would create interface for those two DAL (I would not call them a models) objects. Where one implementation variant would be this Sql::... thing. Then, I would create IArticleOperations service, which receives injected IArticle and ILog implementations with method add, I guess. Then I would create its implementation where method add calls those two methods from DAL objects.

I have suspicion that your question might be a bit different. Might be you wish to log each time you add a new business model (not only this Article)?

Upvotes: 1

Related Questions