attr_bucket 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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