Reputation:
I'm trying to implement a "Popular Products" feature. Basically, every time a Product is viewed, I want to log to the database the number of views of that product. Where do I put the hooks for something like this? I have seen things that are based on building some sort of traffic analytics, but I am looking for ideas that would keep this feature more coupled to the RoR app.
Upvotes: 2
Views: 1027
Reputation: 461
I like google analitics for this kinda thing, then use the API to pull the figures into your app.
This negates any "false" reads and theres a ton of other info you can track and log.
Upvotes: 0
Reputation: 302
I would say keep track of some stats in a separate table. For example:
products_views
--
product_id user_id ip_address created_at updated_at
That way you don't have to worry about locking updating the views field in the database if two people are viewing at the same time. You could then process this table in the background to roll up stats.
Upvotes: 0
Reputation: 441
Writing to a @product.views
counter like @eelco.lempsink.nl says might be a perfectly working basic solution but IMHO there would be significant scalability issues like:
Maybe a more scalable (but very non RoR) solution would be to take server logs and run batch processes to run popularity calculations (like unique per IP etc) and then update this info into a RoR model.
Upvotes: 3
Reputation: 2718
Depending on how you're presenting the stuff, and what you really want to do with the views, you might want to punt on this altogether and use something like Google/Microsoft analytics. They've put a ton of time into their products that will let you see all kinds of info about your traffic over time.
Upvotes: 0
Reputation: 5119
A views field like eelco.lempsink.nl suggested should probably work. And to get the most popular items you add something like:
:sort => "views DESC",
But make really sure that only views of the item by humans is counted. If the count is encreased each time the item is displayed in the list of popular items, you'll get a feedback loop messing up the popularity system. Allso make sure that webcrawlers is not allowed to change the view status.
Allso you really should consider what you want to measure, the amount of people interested in a product, or the amount fooled by a misleading thumbnail and high popularity ranking into clicking on a product.
If this is a webshop or similar, you're probably better off counting the number of buyers instead of views. That would more correctly measure real interest in the product (because they were actually interested enough to spend money on it), and allso I think writing to the database for a view sounds a little unwise (there's massively more views than buys). You'll get better data than a views
field wich may suffer from feedback problems anyway, because you can have popularity history by selecting the count of order
rows for a product with timestamp within a certain timeframe. Getting the orders from the last week or so would probably not be so expensive (for very long timespans the result should probably be cached).
Upvotes: 1
Reputation: 1607
I assume there is a 'view' method in the controller, doing something like
@product = Product.find(params[:id])
If the product has a 'views' field, you can do something like
@product.views = @product.views + 1
@product.save
Upvotes: 4