laracasts/Commander

Related Models

Closed this issue · 6 comments

I've been struggling with how to handle related models.

At the moment, my requirement is to associate an image with a post.

post = [
    'body' => 'body text',
    'image_ids' => [1,2]
];

I validate the data and execute a new PublishPostCommand.

Should there be an AttachImagesToPostCommand? (and if so, how do we get the Post model outside the command?)

Or, within the PublishPostCommand should there be a repository call like:

$this->postRepository->save($post);
$this->postRepostiory->attachImages($command->image_ids);

(and if so, how do we get the Post model outside the postRepository?)

Or, within the save method of the postRepository, should there be logic to handle the attachment? (if, then attach statements)?

$this->postRepository->save($post, $command->image_ids);

I hope the question is clear. None of my solutions fall into place so I'm assuming I'm missing something.

Thanks to anyone who can help.

... at the end of the tunnel I'm assuming there's something like this in the postRepository

public function attachImage(Post $post, $image_ids)
{
    foreach($image_ids as $image_id)
    {
        $post->images()->associate($image_id);
    }
}

I do still want to figure out the proper way to handle this situation, but I am now seeing that it should probably be handled within the command handler calling the repository.

another option could be to have that logic in models (not every time i guess ;) )
in Post.php [model]

public static function createPost($postData, $image_ids)
{
    $post = new static($postData);
    $post->save();
    foreach ($image_ids as $image_id) {
        $post->images()->associate($image_id);
    }
}

All of this comes back to whether the code you need to add is an implementation detail or not. I like to break it down to "what is the end user actually trying to accomplish?" If the answer to that question is simply to publish a post, then I'd store the image attachment stuff within the handler.

Also how to decide whether to do persistence by model ( eg.

$post->save(); 

or by repo.

$postRepo->savePost($post);

first option makes model aware of persistence implementation of framework, exception handling etc. which deviates from its purpose, also it would be handy to tackle persistence in handler if it is part of a transaction.

I think it's a project decision. My way is always handle through repositories.

Yep - that's just an architecture decision.