Skip to content

Instantly share code, notes, and snippets.

@iamjohnlong
Last active January 3, 2016 19:49
Show Gist options
  • Save iamjohnlong/8511379 to your computer and use it in GitHub Desktop.
Save iamjohnlong/8511379 to your computer and use it in GitHub Desktop.
# I have a hash `dates` that I get from "DateTime.now - 7, DateTime.now" in my database.
# I need to turn it into a full week where if the date doesn't exist put a 0 in as the value of the date key.
dates = {"2014-01-15"=>1, "2014-01-17"=>1, "2014-01-18"=>1, "2014-01-19"=>17}
week_hash = {
"2014-01-13"=>0,
"2014-01-14"=>0,
"2014-01-15"=>1,
"2014-01-16"=>0,
"2014-01-17"=>1,
"2014-01-18"=>1,
"2014-01-19"=>17
}
@piersadrian
Copy link

It sounds like what you're looking for is a "default" value for the hash. Just set

dates.default = 0

or

dates = Hash.new(0)
dates.merge({"2014-01-15" => 1, "2014-01-17" => 1, "2014-01-18" => 1, "2014-01-19" => 17})

That way, when you try to access a key that doesn't exist yet, like "2014-01-13", you'll just get back 0 for its value. Does that work? It saves you from wasting lots of space filling up "blank" values in your hash, and saves you having to write "blank" values into the hash at all.

@iamjohnlong
Copy link
Author

Here is what I came up with

amount = @profile.impressions.where("created_at >= ? and created_at <= ?", DateTime.now - 7, DateTime.now)
dates = {}
(1.week.ago.to_date..Date.today).each {|x| dates[x.strftime("%Y-%m-%d")] = 0 }
dates.merge!(amount.count( :group => "message", :order => "message ASC"))

I'm writing it to an api so I can show how many views a profile had in the past week, so I want it in a full week json bag like so:

"views": [
    {
      "date": "2014-01-12",
      "count": 0
    },
    {
      "date": "2014-01-13",
      "count": 0
    },
    {
      "date": "2014-01-14",
      "count": 0
    },
    {
      "date": "2014-01-15",
      "count": 1
    },
    {
      "date": "2014-01-16",
      "count": 0
    },
    {
      "date": "2014-01-17",
      "count": 1
    },
    {
      "date": "2014-01-18",
      "count": 1
    },
    {
      "date": "2014-01-19",
      "count": 17
    }
  ]

I believe this will work for me.

@iamjohnlong
Copy link
Author

I do get these warnings though

DEPRECATION WARNING: Relation#calculate with finder options is deprecated. Please build a scope and then call calculate on it instead. (called from show at /Users/johnlong/Projects/yak/app/controllers/api/v1/user_profile_controller.rb:12)
DEPRECATION WARNING: The :distinct option for `Relation#count` is deprecated. Please use `Relation#distinct` instead. (eg. `relation.distinct.count`). (called from show at /Users/johnlong/Projects/yak/app/controllers/api/v1/user_profile_controller.rb:12)

It seems this is where it's coming from

amount.count( :group => "message", :order => "message ASC")

@piersadrian
Copy link

Looks good! Yeah, needing to serialize that data into a JSON object is definitely a different story. One quick thing: you're generating two equivalent dates two different ways at two different times. If your database connection stalls for a few seconds, you could accidentally end up with mismatched results. Just generate your date once, like

week_ago = Date.today - 7

so you don't end up with time mismatches. The deprecation warnings are because that's the old Rails 3.x syntax for .count. Look into the .group and .order methods instead.

@iamjohnlong
Copy link
Author

Thanks dood! @piersadrian

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment