Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>Use meaningful table names</h2> <p>Based on your requirements you can name the table that logs views for example "post_views" (i.e. the viewing of a post by a user):</p> <pre><code>tbl_post_views -id -user_id -post_id </code></pre> <p>If <code>tbl_</code> isn't a prefix - remove it be conventional.</p> <p>Therefore there would be a model named PostView belonging to both post and user:</p> <pre><code>class PostView extends AppModel { public $belongsTo = array('Post', 'User'); } </code></pre> <h2>Don't use your view action to track a view</h2> <p>Most likely the current intention is to implement something like this:</p> <pre><code>class PostsController extends AppController { public $uses = array('Post', 'PostView'); public function view($id) { $this-&gt;PostView-&gt;save(array('user_id' =&gt; $this-&gt;Auth-&gt;user('id'), 'post_id' =&gt; $id)); $data = $this-&gt;Post-&gt;findById($id); $this-&gt;set(compact('data')); } } </code></pre> <p>It's a better idea to <em>not</em> do that. Recording the view in the controller code has two significant-ish problems:</p> <ol> <li>It's recording generating a view, not the user seeing it (not necessarily the same thing)</li> <li>It interferes with caching (either in php or a user's browser)</li> </ol> <h2>Use an image beacon</h2> <p>Instead of recording a view when the request is made, include an "image beacon" in the rendered output:</p> <pre><code>// end of file View/Posts/view.ctp echo $this-&gt;Html-&gt;image(array('action' =&gt; 'viewed', $postId), array('class' =&gt; 'beacon')); </code></pre> <p>And in your posts controller - record that the post has been viewed, and output a valid image (otherwise there will be an error reported by the user's browser) with appropriate headers to never cache the response:</p> <pre><code>class PostsController extends AppController { ... public function viewed($id) { $this-&gt;PostView-&gt;save(array('user_id' =&gt; $this-&gt;Auth-&gt;user('id'), 'post_id' =&gt; $id)); $this-&gt;response-&gt;disableCache(); $this-&gt;response-&gt;file('webroot/img/1px.gif'); // a 1px gif return $this-&gt;response; } } </code></pre> <p>In this way, irrespective of how the user gets to read the content, there is a record that the user viewed the relevant page.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload