attr_bucket 0.2.0 → 0.2.1
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.
- data/lib/attr_bucket.rb +45 -7
- data/lib/attr_bucket/version.rb +1 -1
- data/spec/attr_bucket_spec.rb +14 -2
- metadata +2 -2
data/lib/attr_bucket.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
module AttrBucket
|
2
2
|
def self.included(base) #:nodoc:
|
3
3
|
base.extend ClassMethods
|
4
|
+
base.class_attribute :bucketed_attributes
|
5
|
+
base.bucketed_attributes = []
|
6
|
+
base.instance_eval do
|
7
|
+
alias_method_chain :assign_multiparameter_attributes, :attr_bucket
|
8
|
+
end
|
4
9
|
end
|
5
10
|
|
6
11
|
private
|
@@ -8,10 +13,10 @@ module AttrBucket
|
|
8
13
|
# Retrieve the attribute bucket, or if it's not yet a Hash,
|
9
14
|
# initialize it as one.
|
10
15
|
def get_attr_bucket(name)
|
11
|
-
unless
|
12
|
-
|
16
|
+
unless self[name].is_a?(Hash)
|
17
|
+
self[name] = {}
|
13
18
|
end
|
14
|
-
|
19
|
+
self[name]
|
15
20
|
end
|
16
21
|
|
17
22
|
def valid_class(value, type)
|
@@ -30,6 +35,17 @@ module AttrBucket
|
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
38
|
+
# We have to override assign_multiparameter_attributes to catch
|
39
|
+
# dates/times for bucketed columns and handle them ourselves
|
40
|
+
# before passing the remainder on for ActiveRecord::Base to handle.
|
41
|
+
def assign_multiparameter_attributes_with_attr_bucket(pairs)
|
42
|
+
bucket_pairs = pairs.select {|p| self.class.bucketed_attributes.include?(p.first.split('(').first)}
|
43
|
+
extract_callstack_for_multiparameter_attributes(bucket_pairs).each do |name, value|
|
44
|
+
send(name + '=', value)
|
45
|
+
end
|
46
|
+
assign_multiparameter_attributes_without_attr_bucket(pairs - bucket_pairs)
|
47
|
+
end
|
48
|
+
|
33
49
|
# Swipe the nifty column typecasting from the column class
|
34
50
|
# underlying the bucket column, or use the call method of
|
35
51
|
# the object supplied for +type+ if it responds to call.
|
@@ -47,10 +63,10 @@ module AttrBucket
|
|
47
63
|
when :integer then value.to_i rescue value ? 1 : 0
|
48
64
|
when :float then value.to_f
|
49
65
|
when :decimal then column_class.value_to_decimal(value)
|
50
|
-
when :datetime then
|
51
|
-
when :timestamp then
|
52
|
-
when :time then
|
53
|
-
when :date then
|
66
|
+
when :datetime then cast_to_time(value, column_class)
|
67
|
+
when :timestamp then cast_to_time(value, column_class)
|
68
|
+
when :time then cast_to_time(value, column_class, true)
|
69
|
+
when :date then cast_to_date(value, column_class)
|
54
70
|
when :binary then column_class.binary_to_string(value)
|
55
71
|
when :boolean then column_class.value_to_boolean(value)
|
56
72
|
else value
|
@@ -61,6 +77,27 @@ module AttrBucket
|
|
61
77
|
typecasted
|
62
78
|
end
|
63
79
|
|
80
|
+
def cast_to_date(value, column_class)
|
81
|
+
if value.is_a?(Array)
|
82
|
+
begin
|
83
|
+
values = value.collect { |v| v.nil? ? 1 : v }
|
84
|
+
Date.new(*values)
|
85
|
+
rescue ArgumentError => e
|
86
|
+
Time.time_with_datetime_fallback(self.class.default_timezone, *values).to_date
|
87
|
+
end
|
88
|
+
else
|
89
|
+
column_class.string_to_date(value)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def cast_to_time(value, column_class, dummy_time = false)
|
94
|
+
if value.is_a?(Array)
|
95
|
+
Time.time_with_datetime_fallback(self.class.default_timezone, *value)
|
96
|
+
else
|
97
|
+
dummy_time ? column_class.string_to_dummy_time(value) : column_class.string_to_time(value)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
64
101
|
module ClassMethods
|
65
102
|
private
|
66
103
|
|
@@ -118,6 +155,7 @@ module AttrBucket
|
|
118
155
|
alias :i_has_a_bucket :attr_bucket
|
119
156
|
|
120
157
|
def define_bucket_reader(bucket_name, attr_name) #:nodoc:
|
158
|
+
self.bucketed_attributes += [attr_name.to_s]
|
121
159
|
define_method attr_name do
|
122
160
|
get_attr_bucket(bucket_name)[attr_name]
|
123
161
|
end unless method_defined? attr_name
|
data/lib/attr_bucket/version.rb
CHANGED
data/spec/attr_bucket_spec.rb
CHANGED
@@ -91,12 +91,18 @@ describe AttrBucket do
|
|
91
91
|
@o.salary.should eq 50000.23
|
92
92
|
end
|
93
93
|
|
94
|
-
it 'typecasts to Time for :datetime' do
|
94
|
+
it 'typecasts to Time for :datetime as string' do
|
95
95
|
@o.hired_at = '2011-01-01 08:00:00'
|
96
96
|
@o.hired_at.should be_a Time
|
97
97
|
@o.hired_at.should eq Time.parse '2011-01-01 08:00:00'
|
98
98
|
end
|
99
99
|
|
100
|
+
it 'typecasts to Time for :datetime as array' do
|
101
|
+
@o.hired_at = [2011, 1, 1, 8, 0]
|
102
|
+
@o.hired_at.should be_a Time
|
103
|
+
@o.hired_at.should eq Time.local(2011, 1, 1, 8, 0)
|
104
|
+
end
|
105
|
+
|
100
106
|
it 'typecasts to Time for :timestamp' do
|
101
107
|
@o.stamp = '2011-01-01 08:00:00'
|
102
108
|
@o.stamp.should be_a Time
|
@@ -109,12 +115,18 @@ describe AttrBucket do
|
|
109
115
|
@o.workday_starts_at.should eq Time.parse '2000-01-01 08:00:00'
|
110
116
|
end
|
111
117
|
|
112
|
-
it 'typecasts to Date for :date
|
118
|
+
it 'typecasts to Date for :date as string' do
|
113
119
|
@o.birthday = '1977/8/29'
|
114
120
|
@o.birthday.should be_a Date
|
115
121
|
@o.birthday.should eq Date.new(1977, 8, 29)
|
116
122
|
end
|
117
123
|
|
124
|
+
it 'typecasts to Date for :date as array' do
|
125
|
+
@o.birthday = [1977,8,29]
|
126
|
+
@o.birthday.should be_a Date
|
127
|
+
@o.birthday.should eq Date.new(1977, 8, 29)
|
128
|
+
end
|
129
|
+
|
118
130
|
it 'typecasts to String for :binary' do
|
119
131
|
@o.binary_data = File.read(__FILE__)
|
120
132
|
@o.binary_data.should be_a String
|