Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writer uses inspect to serialize object #43

Open
ressu opened this issue Nov 20, 2012 · 2 comments · May be fixed by #63
Open

Writer uses inspect to serialize object #43

ressu opened this issue Nov 20, 2012 · 2 comments · May be fixed by #63

Comments

@ressu
Copy link

ressu commented Nov 20, 2012

Inspect is meant to provide a human readable output of an object. It's not always guaranteed that it can be read in to a new object. For example Date objects fail to be imported again.

Consider the following:

['2001-01-01'.to_date].inspect
=> "[Mon, 01 Jan 2001]"
@garysweaver
Copy link

The quick and dirty way to fix this is (and you might not need first two lines):

# Depending on what has been predefined, these may need to be required.
require 'date' unless defined?(DateTime)
require 'time' unless Time.respond_to?(:iso8601)

class ActiveSupport::TimeWithZone
  def inspect
    "DateTime.iso8601(#{iso8601.inspect})"
  end
end if defined?(ActiveSupport::TimeWithZone) 

class DateTime
  def inspect
    "DateTime.iso8601(#{iso8601.inspect})"
  end
end

class Date
  def inspect
    "Date.iso8601(#{iso8601.inspect})"
  end
end

class Time
  def inspect
    "Time.iso8601(#{iso8601.inspect})"
  end
end

If you put this into a rake task at the root of the task code, it may leak into use of the annotations gem, etc. which rely on normal inspect behavior for Date/Time/DateTime. One way to handle this problem is to only patch them when you have a rake task that would (typically) only run from command-line, and eval the patch in the method body, being sure to use fully-defined module/class refs, just in case, e.g.

namespace :db do
  namespace :seed do
    task :some_task ... do |task, args|
      # patch inspects
      eval <<-EOS
      class ::ActiveSupport::TimeWithZone
        def inspect
          "DateTime.iso8601(\#{iso8601.inspect})"
        end
      end

      class ::DateTime
        def inspect
          "DateTime.iso8601(\#{iso8601.inspect})"
        end
      end

      class ::Date
        def inspect
          "Date.iso8601(\#{iso8601.inspect})"
        end
      end

      class ::Time
        def inspect
          "Time.iso8601(\#{iso8601.inspect})"
        end
      end
EOS

      # ... and use SeedFu::Writer.write somewhere under that
    end
  end
end

That wouldn't completely stop the patch from getting in the way, but it would limit havoc.

I also attempted a patch to seed-fu in #63 that doesn't require overriding inspect, because I doubt people want seed-fu changing inspect behavior on Date/Time/DateTime/ActiveSupport::TimeWithZone.

@johnpray
Copy link

👍 to this. Without either @garysweaver's monkeypatch or #63, seed-fu's Writer is useless for times and dates.

For now I'm using the second monkeypatch @garysweaver posted above (limiting its effects to a single rake task). Thanks for that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants