Tracking user activity daily for 30 days

Is this a valid and proper design to keep a track of user activity daily for 30 days?

class AddDayNumbersToUserActivitesForTracking < ActiveRecord::Migration
  def change
  	add_column :user_activities,:day1,:integer
  	add_column :user_activities,:day2,:integer
  	add_column :user_activities,:day3,:integer
  	add_column :user_activities,:day4,:integer
  	add_column :user_activities,:day5,:integer
  	add_column :user_activities,:day6,:integer
  	add_column :user_activities,:day7,:integer
  	add_column :user_activities,:day8,:integer
  	add_column :user_activities,:day9,:integer
  	add_column :user_activities,:day10,:integer
  	add_column :user_activities,:day11,:integer
  	add_column :user_activities,:day12,:integer
  	add_column :user_activities,:day13,:integer
  	add_column :user_activities,:day14,:integer
  	add_column :user_activities,:day15,:integer
  	add_column :user_activities,:day16,:integer
  	add_column :user_activities,:day17,:integer
  	add_column :user_activities,:day18,:integer
  	add_column :user_activities,:day19,:integer
  	add_column :user_activities,:day20,:integer
  	add_column :user_activities,:day21,:integer
  	add_column :user_activities,:day22,:integer
  	add_column :user_activities,:day23,:integer
  	add_column :user_activities,:day24,:integer
  	add_column :user_activities,:day25,:integer
  	add_column :user_activities,:day26,:integer
  	add_column :user_activities,:day27,:integer
  	add_column :user_activities,:day28,:integer
  	add_column :user_activities,:day29,:integer
  	add_column :user_activities,:day30,:integer
  end
end



  create_table "user_activities", force: true do |t|
    t.integer  "user_id"
    t.integer  "challenge_id"
    t.datetime "start_time"
    t.datetime "end_time"
    t.integer  "steps_covered"
    t.string   "status"
    t.integer  "day1"
    t.integer  "day2"
    t.integer  "day3"
    t.integer  "day4"
    t.integer  "day5"
    t.integer  "day6"
    t.integer  "day7"
    t.integer  "day8"
    t.integer  "day9"
    t.integer  "day10"
    t.integer  "day11"
    t.integer  "day12"
    t.integer  "day13"
    t.integer  "day14"
    t.integer  "day15"
    t.integer  "day16"
    t.integer  "day17"
    t.integer  "day18"
    t.integer  "day19"
    t.integer  "day20"
    t.integer  "day21"
    t.integer  "day22"
    t.integer  "day23"
    t.integer  "day24"
    t.integer  "day25"
    t.integer  "day26"
    t.integer  "day27"
    t.integer  "day28"
    t.integer  "day29"
    t.integer  "day30"
  end

  add_index "user_activities", ["user_id", "challenge_id"], name: "index_user_activities_on_user_id_and_challenge_id"

I wouldn’t recommend you go with this approach. It has many flaws. Every time you’d have to update each user record so that day1 becomes day2 etc. Why don’t you go with a schema where each user has a couple of activity models and you just query those? Something like this:

class User
  has_many :activities
end

class Activity
  belongs_to :user
end

And each activity would have a timestamp field and an activity type.

With this approach you’re not limited to 30 fields you’ve created in the database as you can add as many records you want and just query the ones you’re interested in. Like User.first.activities.limit(30).

You might also like the public_activity gem (there’s also railscast episode on it). Hope it helps!

How will day1 become day2? Day1 will referring to the start_time and the other days will be relative to that day 1.

What I could do is UserActivity has_many :activities and each Activity has :number_of_steps_covered_for_that_day and a timestamp.

So User has_many UserActivities. I would not need to put User has_many activities,through: user_activities since I dont think I would be need activities from user as each UserActivity also belongs to a particular Challenge.

Since you haven’t described what you want your code to do (what it is used for) it’s hard for me - hence anyone - to give you the perfect solution. But trust me that you need to rethink the schema :wink:

Oh yes, I was just changing the schema. So each User joins a challenge. for example a monthly challenge in which he needs to do 10k steps a day. And I need to keep a track his daily steps.

So what I did is when a user joins a challenge I create a UserActivity(user:User, challenge: challenge)
which keeps a track of users daily activity/ report for that challenge.

Now I need a way where the user feeds in his daily activity or the number of steps and I store it somewhere.

You could either track number of steps a user completes in the UserActivity model or create a separate model for that.

# One way
class UserActivity
  has_many :challenge_activities
end

class ChallengeActivity
  belongs_to :user
  belongs_to :user_activity
  # has properties: completed_at, steps
end

Ok yeah I could that. But now I need the user to go his profile and enter his number of steps for each day as the days pass. I am stuck at this. Should I go for nested_attributes?

I want to ask the user the number of steps he has covered in the last day.