Want to receive a weekly email containing
the scoop on our new titles along with the
occasional special offer? Just click the button.
(You can always unsubscribe later by editing your
account information).

Give us an email and a password (you can use the password later to log in and
change your preferences). We'll send you a newsletter roughly once a week.

(Yes, it can be done in one line, using a semi-colon as a delimiter, but I think the above is clearer)

Then, I’d set an instance variable to this value in each of the actions I wanted to count

def index
# ...
@count = increment_count
end

Mark says:

that would sum all the counted actions though, wouldn’t it – as the session :count variable can’t differentiate between actions. so if you’d viewed the index action 3 times and the add_to_cart action twice, the count would show as 5.

Chas says:

No Mark, it wouldn’t. Dave has placed the call to increment_count inside the index action and not the add_to_cart action, the result is increment_count is only called when the index action has been called.

Chris says:

Aaron,

There are two issues with that code. The main problem is that if someone views the index for the first time, their count will be 0 instead of 1. You can either remedy this by setting the counter variable to 1 instead of 0, or pull the counter incremental outside of the if/else construct.

The second issue, which is more minor, is that it’s one of those bits of code that feels like it should be pulled out into its own private method. If you ever decide to expand it to another action, then pulling it out will make the work nice and DRY. (Of course, you could refactor when the need arises) I’m pretty poor at explaining myself on why it would be separate, and in reality, it could be contained within the index action, but my general rule of thumb is that if I think I might be served by making a method out of it, then I always do.

Benjamin asserts:

This is what I tried, and it works pretty well. I understand the appeal of creating another function to handle the counter setting, but I prefer not to when we’re only using it once. If we used the counter functionality on other pages, I would probably abstract it like mentioned above.

The first line of the action takes advantage of assignment chaining. It sets session[:counter] to 0 if session[:counter] doesn’t exist (is equal to nil). It then adds one to session[:counter] and sets @count to that new value.

Keep in mind there is still a required reset later on in the add_to_cart action, but this takes care of the initialization and increment.

Claudio says:

Personally, I like to extract the method (I called mine increment_index_access_counter) to simply reveal the intention of the code and hide the pure technicality of having to initialize the session counter. I think it reads better when you avoid mixing business objects (product), with somewhat technical aspects (session[:counter]) in the same method.

Wael says:

What I did was pretty simple, I added an increment_counter function, a protected one with the same code mentioned here.