coaster 0.4.7 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/coaster/core_ext/array.rb +11 -0
- data/lib/coaster/core_ext/date.rb +5 -0
- data/lib/coaster/core_ext/month.rb +108 -0
- data/lib/coaster/core_ext.rb +3 -0
- data/lib/coaster/serialized_properties.rb +193 -0
- data/lib/coaster/version.rb +1 -1
- metadata +20 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f3443395e8b26f474e4d170c1dd1e3edea41cf9
|
4
|
+
data.tar.gz: 482a7957080674361a16c29a6284e7f819c8248e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27ff86f49682b3bfc97c2e9f335fb1a01921b524541b7d7c5f11c283f5bd6afb50a798bcfa4748d4bbf4c457707705e2826f2c5fd4d4c431017c7f4e02bb5eb3
|
7
|
+
data.tar.gz: a109aefbd31130b58d721a92a365f3b726b4afe0854ef7a4b94872545f20332fe6f589629eb6d1952f474f30891b79d93c894204a5df503977e1b29fafac3bf7
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'attr_extras' # gem
|
2
|
+
|
3
|
+
class Month
|
4
|
+
vattr_initialize :year, :month
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def from(object)
|
8
|
+
case object
|
9
|
+
when Month then object
|
10
|
+
when String then Month.parse(object)
|
11
|
+
when Array then Month.new(object[0], object[1])
|
12
|
+
else new(object.year, object.month)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Month.parse('201601')
|
17
|
+
# Month.parse('2016-01')
|
18
|
+
def parse(str)
|
19
|
+
date = Date.parse(str)
|
20
|
+
from(date)
|
21
|
+
rescue ArgumentError => e
|
22
|
+
if str.instance_variable_get(:@_gsub_)
|
23
|
+
raise e, str: str.instance_variable_get(:@_gsub_)
|
24
|
+
elsif e.message != 'invalid date'
|
25
|
+
raise e, str: str
|
26
|
+
end
|
27
|
+
str_gsub = str.gsub(/[^\d]/, '')
|
28
|
+
str_gsub.insert(4, '0') if str_gsub.length == 5
|
29
|
+
str_gsub += '01'
|
30
|
+
str_gsub.instance_variable_set(:@_gsub_, str_gsub)
|
31
|
+
parse(str_gsub)
|
32
|
+
end
|
33
|
+
|
34
|
+
def current
|
35
|
+
from(Date.current)
|
36
|
+
end
|
37
|
+
|
38
|
+
def now
|
39
|
+
from(Time.zone.now)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def year
|
44
|
+
Integer(@year)
|
45
|
+
end
|
46
|
+
|
47
|
+
def month
|
48
|
+
Integer(@month)
|
49
|
+
end
|
50
|
+
|
51
|
+
def first_date
|
52
|
+
Date.new(year, month, 1)
|
53
|
+
end
|
54
|
+
|
55
|
+
def last_date
|
56
|
+
Date.new(year, month, -1)
|
57
|
+
end
|
58
|
+
|
59
|
+
def first_day
|
60
|
+
first_date.day
|
61
|
+
end
|
62
|
+
|
63
|
+
def last_day
|
64
|
+
last_date.day
|
65
|
+
end
|
66
|
+
|
67
|
+
def beginning_of_month
|
68
|
+
first_date.beginning_of_day
|
69
|
+
end
|
70
|
+
|
71
|
+
def end_of_month
|
72
|
+
last_date.end_of_day
|
73
|
+
end
|
74
|
+
|
75
|
+
def date_for_day(number)
|
76
|
+
Date.new(year, month, number)
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_time_range
|
80
|
+
beginning_of_month...(later.beginning_of_month)
|
81
|
+
end
|
82
|
+
|
83
|
+
def previous
|
84
|
+
self.class.from(first_date - 1)
|
85
|
+
end
|
86
|
+
|
87
|
+
def later
|
88
|
+
self.class.from(last_date + 1)
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_s
|
92
|
+
"#{year}-#{month}"
|
93
|
+
end
|
94
|
+
alias_method :inspect, :to_s
|
95
|
+
|
96
|
+
def -(time)
|
97
|
+
first_date - time
|
98
|
+
end
|
99
|
+
|
100
|
+
def +(time)
|
101
|
+
first_date + time
|
102
|
+
end
|
103
|
+
|
104
|
+
include Comparable
|
105
|
+
def <=>(other)
|
106
|
+
first_date <=> Month.from(other).first_date
|
107
|
+
end
|
108
|
+
end
|
data/lib/coaster/core_ext.rb
CHANGED
@@ -0,0 +1,193 @@
|
|
1
|
+
module Coaster
|
2
|
+
module SerializedProperties
|
3
|
+
class DuplicatedProperty < StandardError; end
|
4
|
+
class InvalidProperty < StandardError; end
|
5
|
+
|
6
|
+
def serialized_property_settings
|
7
|
+
@serialized_property_settings ||= {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialized_property_setting(key)
|
11
|
+
serialized_property_settings[key.to_sym]
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialized_column(serialize_column)
|
15
|
+
define_method serialize_column.to_sym do
|
16
|
+
return read_attribute(serialize_column.to_sym) if read_attribute(serialize_column.to_sym)
|
17
|
+
write_attribute(serialize_column.to_sym, {})
|
18
|
+
read_attribute(serialize_column)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def serialized_property_comment(key)
|
23
|
+
cm = serialized_property_settings[key.to_sym] &&
|
24
|
+
serialized_property_settings[key.to_sym][:comment]
|
25
|
+
cm || key.to_s
|
26
|
+
end
|
27
|
+
|
28
|
+
def serialized_property(serialize_column, key, type: nil, comment: nil, getter: nil, setter: nil, setter_callback: nil, default: nil)
|
29
|
+
raise DuplicatedProperty, "#{self.name}##{key} duplicated\n#{caller[0..5].join("\n")}" if serialized_property_settings[key.to_sym]
|
30
|
+
serialized_property_settings[key.to_sym] = {type: type, comment: comment, getter: getter, setter: setter, setter_callback: setter_callback, default: default}
|
31
|
+
_typed_serialized_property(serialize_column, key, type: type, getter: getter, setter: setter, setter_callback: setter_callback, default: default)
|
32
|
+
end
|
33
|
+
|
34
|
+
def serialized_properties(serialize_column, *keys, type: nil, getter: nil, setter: nil, setter_callback: nil, default: nil)
|
35
|
+
keys.flatten.each do |key|
|
36
|
+
key_name = key
|
37
|
+
prop_hash = {type: type, getter: getter, setter: setter, setter_callback: setter_callback, default: default}
|
38
|
+
if key.is_a? Hash
|
39
|
+
key_name = key[:key]
|
40
|
+
prop_hash = {type: type, getter: getter, setter: setter, setter_callback: setter_callback, default: default}.merge(key)
|
41
|
+
prop_hash.delete(:key)
|
42
|
+
end
|
43
|
+
serialized_property(serialize_column, key_name, prop_hash)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def _typed_serialized_property(serialize_column, key, type: nil, getter: nil, setter: nil, setter_callback: nil, default: nil)
|
50
|
+
case type
|
51
|
+
when String then
|
52
|
+
# String은 나중에 eval해서 가져옴,
|
53
|
+
# type에서 다른 객체를 참조할 경우, 순환참조가 발생할 수 있기 때문에
|
54
|
+
Rails.configuration.after_initialize {
|
55
|
+
if type.is_a?(String)
|
56
|
+
begin
|
57
|
+
type = eval(type)
|
58
|
+
raise InvalidProperty, "#{self.name}##{key} type string is return string #{type}" if type.is_a?(String)
|
59
|
+
rescue InvalidProperty => e
|
60
|
+
raise
|
61
|
+
rescue => e
|
62
|
+
raise InvalidProperty, "#{self.name}##{key} eval failed: type:[#{type}] [#{e.class.name}] #{e.message}"
|
63
|
+
end
|
64
|
+
serialized_property_setting(key.to_sym)[:type] = type
|
65
|
+
_typed_serialized_property serialize_column, key, type: type, getter: getter, setter: setter, setter_callback: setter_callback, default: default
|
66
|
+
end
|
67
|
+
}
|
68
|
+
when Array then
|
69
|
+
_define_serialized_property serialize_column, key,
|
70
|
+
setter: proc { |val|
|
71
|
+
raise InvalidProperty, "#{self.name}##{key} must be one of #{type}" unless type.include?(val)
|
72
|
+
val
|
73
|
+
},
|
74
|
+
getter: proc { |val|
|
75
|
+
type.include?(val) ? val : nil
|
76
|
+
}
|
77
|
+
else
|
78
|
+
if type == Time
|
79
|
+
_define_serialized_property serialize_column, key,
|
80
|
+
getter: Proc.new { |val| val.nil? ? nil : Time.zone.parse(val) },
|
81
|
+
setter: Proc.new { |val| val.is_a?(Time) ? val.to_s(:default_tz) : nil}
|
82
|
+
elsif type == Integer
|
83
|
+
_define_serialized_property serialize_column, key,
|
84
|
+
setter: proc { |val|
|
85
|
+
val = val.blank? ? nil : Integer(val)
|
86
|
+
val = setter.call(val) if setter
|
87
|
+
val
|
88
|
+
}
|
89
|
+
elsif type == Array
|
90
|
+
_define_serialized_property(serialize_column, key, default: [])
|
91
|
+
elsif type && type < ActiveRecord::Base
|
92
|
+
_define_serialized_property serialize_column, "#{key}_id"
|
93
|
+
|
94
|
+
define_method key.to_sym do
|
95
|
+
instance_val = instance_variable_get("@#{key}".to_sym)
|
96
|
+
return instance_val if instance_val
|
97
|
+
key_id = send("#{key}_id".to_sym)
|
98
|
+
if key_id.nil?
|
99
|
+
instance_val = nil
|
100
|
+
else
|
101
|
+
instance_val = type.find(key_id) rescue nil
|
102
|
+
instance_variable_set("@#{key}".to_sym, instance_val)
|
103
|
+
end
|
104
|
+
instance_val = getter.call(instance_val) if getter
|
105
|
+
instance_val
|
106
|
+
end
|
107
|
+
|
108
|
+
define_method "#{key}=".to_sym do |val|
|
109
|
+
val = setter.call(val) if setter
|
110
|
+
|
111
|
+
if val.nil?
|
112
|
+
instance_variable_set("@#{key}".to_sym, nil)
|
113
|
+
send("#{key}_id=".to_sym, nil)
|
114
|
+
else
|
115
|
+
unless val.is_a?(type)
|
116
|
+
raise ActiveRecord::AssociationTypeMismatch, "#{type}(##{type.object_id}) expected, got #{val.class.name}(#{val.class.object_id})"
|
117
|
+
end
|
118
|
+
instance_variable_set("@#{key}".to_sym, val)
|
119
|
+
send("#{key}_id=".to_sym, (Integer(val.id) rescue val.id))
|
120
|
+
end
|
121
|
+
|
122
|
+
if setter_callback
|
123
|
+
setter_callback.call(val)
|
124
|
+
else
|
125
|
+
val
|
126
|
+
end
|
127
|
+
end
|
128
|
+
else
|
129
|
+
_define_serialized_property serialize_column, key, getter: getter, setter: setter, setter_callback: setter_callback, default: default
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def _define_serialized_property(serialize_column, key, getter: nil, setter: nil, setter_callback: nil, default: nil)
|
135
|
+
if default
|
136
|
+
if getter
|
137
|
+
define_method key.to_sym do
|
138
|
+
hsh = send(serialize_column.to_sym)
|
139
|
+
hsh[key.to_s] ||= default.dup
|
140
|
+
getter.call(hsh[key.to_s])
|
141
|
+
end
|
142
|
+
else
|
143
|
+
define_method key.to_sym do
|
144
|
+
hsh = send(serialize_column.to_sym)
|
145
|
+
hsh[key.to_s] ||= default.dup
|
146
|
+
end
|
147
|
+
end
|
148
|
+
else
|
149
|
+
if getter
|
150
|
+
define_method key.to_sym do
|
151
|
+
hsh = send(serialize_column.to_sym)
|
152
|
+
getter.call(hsh[key.to_s])
|
153
|
+
end
|
154
|
+
else
|
155
|
+
define_method key.to_sym do
|
156
|
+
hsh = send(serialize_column.to_sym)
|
157
|
+
hsh[key.to_s]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
if setter
|
163
|
+
define_method "#{key}_without_callback=".to_sym do |val|
|
164
|
+
if val.nil?
|
165
|
+
send(serialize_column.to_sym).delete(key.to_s)
|
166
|
+
else
|
167
|
+
val = setter.call(val) if setter
|
168
|
+
send(serialize_column.to_sym)[key.to_s] = val
|
169
|
+
end
|
170
|
+
end
|
171
|
+
else
|
172
|
+
define_method "#{key}_without_callback=".to_sym do |val|
|
173
|
+
if val.nil?
|
174
|
+
send(serialize_column.to_sym).delete(key.to_s)
|
175
|
+
else
|
176
|
+
send(serialize_column.to_sym)[key.to_s] = val
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
if setter_callback
|
182
|
+
define_method "#{key}=".to_sym do |val|
|
183
|
+
send("#{key}_without_callback=".to_sym, val)
|
184
|
+
setter_callback.call(val)
|
185
|
+
end
|
186
|
+
else
|
187
|
+
define_method "#{key}=".to_sym do |val|
|
188
|
+
send("#{key}_without_callback=".to_sym, val)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
data/lib/coaster/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- buzz jung
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -64,6 +64,20 @@ dependencies:
|
|
64
64
|
- - "<"
|
65
65
|
- !ruby/object:Gem::Version
|
66
66
|
version: '8.0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: attr_extras
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
type: :runtime
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
67
81
|
- !ruby/object:Gem::Dependency
|
68
82
|
name: bundler
|
69
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,9 +202,13 @@ files:
|
|
188
202
|
- lib/coaster.rb
|
189
203
|
- lib/coaster/backtrace_cleaner.rb
|
190
204
|
- lib/coaster/core_ext.rb
|
205
|
+
- lib/coaster/core_ext/array.rb
|
206
|
+
- lib/coaster/core_ext/date.rb
|
207
|
+
- lib/coaster/core_ext/month.rb
|
191
208
|
- lib/coaster/core_ext/object_translation.rb
|
192
209
|
- lib/coaster/core_ext/standard_error.rb
|
193
210
|
- lib/coaster/core_ext/standard_error/raven.rb
|
211
|
+
- lib/coaster/serialized_properties.rb
|
194
212
|
- lib/coaster/version.rb
|
195
213
|
- test/locales/en.yml
|
196
214
|
- test/test_helper.rb
|