Which data model is optimal for a simple tracker of user views?
Here's more of an academic question for you guys. Say I want to create a model in a ruby on rails app to track simple views information. I would like to record the user_id, the URI for the page viewed, and keep track of the number of times the user has visited a pa开发者_如何学Pythonge.
Model A: One way to do this would be to create a model View with attributes user_id and page (records the uri), and then create a new entry every time a user opens a page.
Model B: A second way to do this would be to add an attribute "page_views" to the model, to track the number of times the user has accessed that page.
Pros and Cons: Model A would have more information recorded and lead to a larger db than Model B. However, Model B would require that a controller search for an existing user-page combination, and either add views to that entry, or create a new one. This leads to a smaller database, but may be worse in scale due to the need to search for existing entries.
So my question to you guys is: which is more important? Are my thoughts wrong? Am I missing something here (other performance considerations overlooked?)
NoSQL approach to tracking user activity:
model app/models/user.rb
class User < ActiveRecord::Base
include UserModules::Tracker
...
end
mixin app/models/user_modules/tracker.rb
module UserModules
module Tracker
def get
key = "user_" + self.id.to_s
arr = Resque.redis.lrange(key, 0, -1)
arr.map{|i| JSON.parse(i)}
end
def put(controller_name, action_name, details="")
key = "user_" + self.id.to_s
created = Time.now.to_formatted_s(:db)}.to_json
# silent exception handle, so you can do not run Redis localy
begin
Resque.redis.rpush key, {
:controller_name => controller_name,
:action_name => action_name,
:details => details,
:created_at => created
rescue
nil
end
end
end
end
controller app/controller/dashboard.rb
class Dashboard < ApplicationController
after_filter :track, :only => :show
# this action will be tracked
def show
end
# this action will show tracking
def logs_show
render :json => current_user.get
end
...
private
def track
details = "any details...."
current_user.put(controller_name, action_name, details)
end
end
You need to have Redis installed, I prefer to use Resque as common way to setup and initialize Redis via Resque.redis, because it will help you to browse your tracking with resque-web
On of the way to setup Redis is in my gist
精彩评论