3

What is the best way to store Time in milliseconds when using Rails+Mysql?

I am about to use a decimal and composed_of in order to be able to manipulate this value as a Ruby Time. Does anyone have a better idea?!

user229044
  • 232,980
  • 40
  • 330
  • 338
Pedro Rolo
  • 28,273
  • 12
  • 60
  • 94
  • 1
    If you need to manipulate the value as a ruby time object, what is the benefit of storing it in milliseconds? – Peter Brown Mar 31 '11 at 12:06
  • I will then be able to order entries according to the value in this attribute and I will not loose relevant info that is meant to be stored in the DB. – Pedro Rolo Mar 31 '11 at 12:37

5 Answers5

2

Several years have passed since this was asked. Here's an updated solution:

https://gist.github.com/MarkMurphy/93adca601b05acffb8b5601df09f66df

Mark Murphy
  • 2,834
  • 1
  • 31
  • 29
1

I'm not sure I fully understand what you're trying to do, but have you considered simply overriding the reader/writer methods in your model?. If this works for you, it might be preferred over your proposed solution since it's arguably more readable.

MyClass < ActiveRecord::Base

  # Override reader method
  def my_attribute
    super().from_milis
  end

  # Override writer method
  def my_attribute=(value)
    super(value.to_milis)
  end

end
Peter Brown
  • 50,956
  • 18
  • 113
  • 146
  • That's what I would have done before learning about rails aggregations. :-) Though, super doesn't work. You should use alias_method_chain instead. – Pedro Rolo Mar 31 '11 at 20:22
  • 1
    Just my opinion, but I don't think you are making the best use of composed_of. Are you getting an error using super? I would expect that to work. It's not the same thing as alias_method_chain, but you could use `read_attribute(:my_attribute)` or `self[:my_attribute]` which are more similar to super() – Peter Brown Mar 31 '11 at 20:40
  • Why do you disagree with the composed_of approach? In my opinion, you should rather use alias_method_chain instead of super because the getters and setters could eventually had already been rewritten with some alias_method_chain call, for instance, when including a module. using super you would loose all this funcionality. – Pedro Rolo Apr 01 '11 at 09:48
0

Posted a solution to store millisecond precision in MySql using composed_of

http://ternarylabs.com/2011/09/26/millisecond-precision-timestamp-in-rails-with-mysql/

-1

1) Store it as a :decimal with ample precision for your purposes.

2) Create a helper method yourself. Something like this:

# app/helpers/application_helper.rb
module ApplicationHelper
  def time_with_ms(time)
    minutes = (time % 1.minute).floor
    seconds = time % 1.minute
    "%02d:%05.2f" % [minutes, seconds]
  end
end
Ashish
  • 5,723
  • 2
  • 24
  • 25
  • Your proposal is less interesting than my former one. you can't possibly have read my question with enough attention. – Pedro Rolo Mar 31 '11 at 11:11
-2

My approach was to:

open the time class and implement the methods :from_milis and :to_milis :

class Time
  def self.from_milis(milis)
    self.at(milis.to_f/1000)
  end

  def to_milis
    self.to_f*1000
  end
end

migrate the column from timestamp to :decimal,:precision=>17

then, in the AR class in which i am using this column as attribute:

composed_of :ts,
    :class_name=>"Time",
    :mapping=>%w(ts to_milis),
    :constructor=>:from_milis,
    :converter=>:from_milis

I just had gochas when using this attribute in arel queries, where I had to explicitly call to_milis in order to get the intended value in the comparision.

Pedro Rolo
  • 28,273
  • 12
  • 60
  • 94
  • I've been able to get this solution working for a new unmanaged by rails column, however I'd like to change the "updated_at" columns so it stores its values in a way that I can retrieve milliseconds. I tried modifying the above to use "updated_at" and even tried modifying ActiveSupport::TimeWithZone as you have modified Time above but I can't quite get it working. It seems rails is doing something else behind the scenes that still needs to be modified. Any ideas? – Streamline Feb 04 '13 at 17:19
  • The updated_at is usually automatically managed by rails and that's probably why you are having trouble with it. I'd suggest using a column with a different name or finding another way to bypass auto-updating this field. – Pedro Rolo Feb 06 '13 at 11:53