3

This may be due to a gap in my understanding of the PHP Object-Oriented model, but bear with me and see if you find it makes any sense/any glaring errors. Anyways, in a MVC app I have two controllers, Post.php and Thread.php. In the Thread controller I have a public method mark_as_read() which does as you could guess. It marks a thread as read (insert row in DB) or updates the time of the last view in the database. In the Thread controller I can call it easily by doing:

$this->mark_as_read($user_id, $thread_id);

However, in the Post controller I also want to be able to mark a thread as read, specifically when I make a new post and I don't want the database to reflect that the user hasn't read their own "new" post. First question: how can I call the mark_as_read() method on a thread from the post controller?

Anyways, I tinkered around and solved this problem in a way which seems very bad to me by instinct. There is a Base controller that both the Post and Thread controllers inherit from. I moved the mark_as_read() method into the base controller, and now I can mark a thread as read by calling the same:

$this->mark_as_read($user_id, $thread_id);

From ANY controller! The reason this seems really bad to me is because I have other controllers where I'm not sure I really want to mark threads as read, and instinctively it doesn't feel like it belongs there. I am pretty sure I'm doing this wrong... so question two: how do I do it the "right" way? I'm using Laravel 3 (http://laravel.com/) but this seems like a general OO PHP question, not specific to the framework.

4
  • If I can answer any clarifying questions feel free to ask... Commented Jun 14, 2013 at 7:22
  • I also thought I could make the method static... but then wouldn't that solution be even uglier? Commented Jun 14, 2013 at 7:22
  • 1
    mark_as_read should be a model action on the thread, not on the controller Commented Jun 14, 2013 at 7:24
  • @Orangepill trying that now.. makes sense to me. Commented Jun 14, 2013 at 7:26

1 Answer 1

3

The first question I would ask is : what class should *mark_as_read(*) belong to ?

The MVC pattern allows you to separate layers : the controller is in charge of organizing the job, it delegates most of the real actions to the view (display stuff) and to the model (any db or data-structure related stuff).

That's why, IMHO, *mark_as_read()* should be a method of the Thread model class. The controller should only call $myThread->mark_as_read() within its actions.

Thus,

  1. any controller can easily mark a thread as read, as long as he has a Thread model instance available.
  2. any post can easily mark its thread as read, since I guess a Post model object has some pointer to its parent thread (emulating the foreign key relationship in the post table of the database)
Sign up to request clarification or add additional context in comments.

5 Comments

Okay so I'm adding it to the model... then how should I call it? Assuming $thread is the appropriate thread object. $thread->mark_as_read($user_id, $thread_id);?
should be able to omit the thread_id unless the instance has an identity crisis
Ah, that's a good point. As I wrote it, it takes 2 params $user_id and $thread_id but if I have it in the thread model, I can just pass the user id and set the thread id to $this->id?
Also if posts and threads dont share an ancestor or child relationship but they do share the same mark_as_read behavior it might be worth creating a separate ReadMarker class to abstract the behavior
Good call. In this case, only threads can be "marked as read" but I can think of extending the app and wanting to do that now...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.