Class: OpenModel

Inherits:
OpenStruct
  • Object
show all
Defined in:
lib/helix_web_services_client/open_model.rb

Overview

A lot of our data coming out of the server has a couple of issues:

  • The ID of an object might be referenced by different cases, or different field names

  • Dates are sometimes as returned as timestamp strings (e.g., "1437153920") and sometimes as rendered strings (e.g., "2015/07/17 10:36:38")

This is intended to be mixed in with an OpenStruct class to let your code handle conversion as needed.

You have a couple of rules:

  1. For [name], if a capitalized version exists we return that

  2. For [name], if a camel case version of the name exists we return that

  3. You can use an "[method]_as_time" to try to detect the format and return it as a ruby Time instance.

    • You must provide an 'offset' parameter here based on the serverTime value from p4 info.

  4. You can use an "[name]or" to fallback to a different symbols.

    rev_or_revision desc_or_description

For example, say you have the Hash

{
  'branch': 'my_branch',
  'Update': "1437153920"
}

Then your object should both respond to:

branch.branch
branch.update_as_time(offset)

This only affects “read” methods. Your code should probably only use the Singular format for “write” methods, and rarely should it ever need to create dates.

Class Method Summary (collapse)

Instance Method Summary (collapse)

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(sym, *args)



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/helix_web_services_client/open_model.rb', line 63

def method_missing(sym, *args)
  match_time = /^(.*)_as_time$/.match(sym.to_s)
  if match_time
    val = send(match_time[1])

    if val =~ /\A[-+]?\d+\z/
      return Time.at(val.to_i)
    elsif OpenModel.date_str?(val) && args.length > 0
      offset = args.first
      return DateTime.parse("#{val} #{offset}").to_time
    end
  end

  mname = sym.id2name

  is_assign = mname.chomp!('=')

  if mname.split('_or_').length > 1
    syms = mname.to_s.split('_or_')
    s = syms.find { |s| @table.key?(OpenModel.capitalize(s).to_sym) }
    if s
      mname = s.to_s
    else
      s = syms.find { |s| @table.key?(OpenModel.camelize(s).to_sym) }
      mname = s.to_s if s
    end
  end

  if @table.key?(OpenModel.capitalize(mname).to_sym)
    mname = OpenModel.capitalize(mname)
  end

  if @table.key?(OpenModel.camelize(mname).to_sym)
    mname = OpenModel.camelize(mname)
  end

  len = args.length
  if is_assign
    if len != 1
      raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
    end
    modifiable[new_ostruct_member(mname)] = args[0]
  elsif len == 0
    @table[mname.to_sym]
  else
    err = NoMethodError.new "undefined method `#{mname.to_sym}' for #{self}", mname.to_sym, args
    err.set_backtrace caller(1)
    raise err
  end
end

Class Method Details

+ (Object) camelize(sym)



54
55
56
# File 'lib/helix_web_services_client/open_model.rb', line 54

def camelize(sym)
  sym.to_s.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
end

+ (Object) capitalize(sym)



50
51
52
# File 'lib/helix_web_services_client/open_model.rb', line 50

def capitalize(sym)
  sym.to_s.split('_').map{ |e| e.capitalize }.join
end

+ (Boolean) date_str?(str)

Returns:

  • (Boolean)


58
59
60
# File 'lib/helix_web_services_client/open_model.rb', line 58

def date_str?(str)
  Date.parse(str) rescue false
end