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 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 read_attribute(name).is_a?(Hash)
12
- write_attribute(name, {})
16
+ unless self[name].is_a?(Hash)
17
+ self[name] = {}
13
18
  end
14
- read_attribute(name)
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 column_class.string_to_time(value)
51
- when :timestamp then column_class.string_to_time(value)
52
- when :time then column_class.string_to_dummy_time(value)
53
- when :date then column_class.string_to_date(value)
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
@@ -1,3 +1,3 @@
1
1
  module AttrBucket
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -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 in string format' do
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
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 0
9
- version: 0.2.0
8
+ - 1
9
+ version: 0.2.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ernie Miller