has_metadata 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -1,7 +1,7 @@
1
1
  h1. has_metadata -- Keep your tables narrow
2
2
 
3
3
  | *Author* | Tim Morgan |
4
- | *Version* | 1.1 (Nov 16, 2010) |
4
+ | *Version* | 1.1.1 (Nov 21, 2010) |
5
5
  | *License* | Released under the MIT License. |
6
6
 
7
7
  h2. Important note for those upgrading from 1.0 to 1.1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.1.1
data/has_metadata.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{has_metadata}
8
- s.version = "1.1.0"
8
+ s.version = "1.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tim Morgan"]
12
- s.date = %q{2010-11-17}
12
+ s.date = %q{2010-11-21}
13
13
  s.description = %q{has_metadata lets you move non-indexed and weighty columns off of your big tables by creating a separate metadata table to store all this extra information. Works with Ruby 1.9. and Rails 3.0.}
14
14
  s.email = %q{git@timothymorgan.info}
15
15
  s.extra_rdoc_files = [
@@ -16,12 +16,46 @@ module HasMetadata
16
16
 
17
17
  # @private
18
18
  def set_fields(fields)
19
- return self if @fields_set
20
- @fields_set = true
21
-
22
- fields.each do |name, _|
23
- singleton_class.send(:define_method, name) { |default=nil| data.include?(name) ? data[name] : default }
24
- singleton_class.send(:define_method, :"#{name}=") { |value| data[name] = value }
19
+ return self if @_fields_set
20
+ @_fields_set = true
21
+
22
+ singleton_class.send(:define_method, :attribute_method?) do |name|
23
+ name = name.to_sym
24
+ super(name) or fields.include?(name)
25
+ end
26
+
27
+ # override attribute prefix/suffix methods to get full first-class
28
+ # property functionality
29
+
30
+ singleton_class.send(:define_method, :attribute) do |name|
31
+ name = name.to_sym
32
+ super(name) unless fields.include?(name)
33
+
34
+ default = (fields[name].kind_of?(Hash) && fields[name][:default]) ? fields[name][:default] : nil
35
+ data.include?(name) ? data[name] : default
36
+ end
37
+ singleton_class.send :alias_method, :attribute_before_type_cast, :attribute
38
+
39
+ singleton_class.send(:define_method, :query_attribute) do |name|
40
+ name = name.to_sym
41
+ super(name) unless fields.include?(name)
42
+
43
+ if fields[name].kind_of?(Hash) and fields[name].include?(:type) then
44
+ if fields[name][:type].ancestors.include?(Numeric) then
45
+ not send(name).zero?
46
+ else
47
+ not send(name).blank?
48
+ end
49
+ else
50
+ not send(name).blank?
51
+ end
52
+ end
53
+
54
+ singleton_class.send(:define_method, :attribute=) do |name, value|
55
+ name = name.to_sym
56
+ super(name, value) unless fields.include?(name)
57
+
58
+ data[name] = value
25
59
  end
26
60
 
27
61
  self
@@ -37,4 +71,4 @@ module HasMetadata
37
71
  data.each { |key, value| data[key] = nil if data[key].blank? }
38
72
  end
39
73
  end
40
- end
74
+ end
data/lib/has_metadata.rb CHANGED
@@ -52,23 +52,19 @@ module HasMetadata
52
52
  #define_method(:metadata_changed?) { metadata and metadata.changed? }
53
53
 
54
54
  fields.each do |name, options|
55
- delegate :"#{name}=", to: :metadata!
55
+ # delegate all attribute methods to the metadata
56
+ attribute_method_matchers.each { |matcher| delegate matcher.method_name(name), to: :metadata! }
56
57
 
57
58
  if options.kind_of?(Hash) then
58
- default = options.delete(:default)
59
- define_method(name) { metadata!.send(name, default) }
59
+ type = options.delete(:type)
60
+ options.delete :default
60
61
 
61
- unless options.empty?
62
- type = options.delete(:type)
63
- validate do |obj|
64
- errors.add(name, :incorrect_type) unless
65
- metadata_typecast(obj.send(name), type).kind_of?(type) or
66
- ((options[:allow_nil] and obj.send(name).nil?) or (options[:allow_blank] and obj.send(name).blank?))
67
- end if type
68
- validates(name, options) unless options.empty? or (options.keys - [ :allow_nil, :allow_blank ]).empty?
69
- end
70
- else
71
- delegate name, to: :metadata!
62
+ validate do |obj|
63
+ errors.add(name, :incorrect_type) unless
64
+ metadata_typecast(obj.send(name), type).kind_of?(type) or
65
+ ((options[:allow_nil] and obj.send(name).nil?) or (options[:allow_blank] and obj.send(name).blank?))
66
+ end if type
67
+ validates(name, options) unless options.empty? or (options.keys - [ :allow_nil, :allow_blank ]).empty?
72
68
  end
73
69
  end
74
70
  end
@@ -13,7 +13,7 @@ module SpecSupport
13
13
  untyped: {},
14
14
  can_be_nil: { type: Date, allow_nil: true },
15
15
  can_be_blank: { type: Date, allow_blank: true },
16
- number: { numericality: true },
16
+ number: { type: Fixnum, numericality: true },
17
17
  multiparam: { type: SpecSupport::ConstructorTester },
18
18
  has_default: { default: 'default' }
19
19
  })
@@ -30,46 +30,44 @@ describe HasMetadata do
30
30
  SpecSupport::HasMetadataTester.nested_attributes_options[:metadata].should_not be_nil
31
31
  end
32
32
 
33
- it "should make a getter for each field" do
34
- SpecSupport::HasMetadataTester.new.should respond_to(:untyped)
35
- SpecSupport::HasMetadataTester.new.should respond_to(:multiparam)
36
- SpecSupport::HasMetadataTester.new.should respond_to(:number)
37
- end
38
-
39
- context "getters" do
40
- before :each do
41
- @object = SpecSupport::HasMetadataTester.new
42
- @metadata = @object.metadata!
43
- end
44
-
45
- it "should return a field in the metadata object" do
46
- @metadata.data[:untyped] = 'bar'
47
- @object.untyped.should eql('bar')
33
+ it "should define methods for each field" do
34
+ [ :attribute, :attribute_before_type_cast, :attribute= ].each do |meth|
35
+ SpecSupport::HasMetadataTester.new.should respond_to(meth.to_s.sub('attribute', 'untyped'))
36
+ SpecSupport::HasMetadataTester.new.should respond_to(meth.to_s.sub('attribute', 'multiparam'))
37
+ SpecSupport::HasMetadataTester.new.should respond_to(meth.to_s.sub('attribute', 'number'))
48
38
  end
39
+ end
49
40
 
50
- it "should return nil if there is no associated metadata" do
51
- @object.stub!(:metadata).and_return(nil)
52
- ivars = @object.instance_variables - [ :@metadata ]
53
- @object.stub!(:instance_variables).and_return(ivars)
54
-
55
- @object.untyped.should be_nil
56
- end
41
+ [ :attribute, :attribute_before_type_cast ].each do |getter|
42
+ describe "##{getter}" do
43
+ before :each do
44
+ @object = SpecSupport::HasMetadataTester.new
45
+ @metadata = @object.metadata!
46
+ end
47
+
48
+ it "should return a field in the metadata object" do
49
+ @metadata.data[:untyped] = 'bar'
50
+ @object.send(getter.to_s.sub('attribute', 'untyped')).should eql('bar')
51
+ end
52
+
53
+ it "should return nil if there is no associated metadata" do
54
+ @object.stub!(:metadata).and_return(nil)
55
+ ivars = @object.instance_variables - [ :@metadata ]
56
+ @object.stub!(:instance_variables).and_return(ivars)
57
+
58
+ @object.send(getter.to_s.sub('attribute', 'untyped')).should be_nil
59
+ end
57
60
 
58
- it "should return a default if one is specified" do
59
- @object.has_default.should eql('default')
60
- end
61
+ it "should return a default if one is specified" do
62
+ @object.send(getter.to_s.sub('attribute', 'has_default')).should eql('default')
63
+ end
61
64
 
62
- it "should return nil if nil is stored and the default is not nil" do
63
- @metadata.data[:has_default] = nil
64
- @object.has_default.should eql(nil)
65
+ it "should return nil if nil is stored and the default is not nil" do
66
+ @metadata.data[:has_default] = nil
67
+ @object.send(getter.to_s.sub('attribute', 'has_default')).should eql(nil)
68
+ end
65
69
  end
66
70
  end
67
-
68
- it "should make a setter for each field" do
69
- SpecSupport::HasMetadataTester.new.should respond_to(:untyped=)
70
- SpecSupport::HasMetadataTester.new.should respond_to(:multiparam=)
71
- SpecSupport::HasMetadataTester.new.should respond_to(:number=)
72
- end
73
71
 
74
72
  context "setters" do
75
73
  before :each do
@@ -131,5 +129,51 @@ describe HasMetadata do
131
129
  @object.multiparam.args.should eql([ 1982, 10.5 ])
132
130
  end
133
131
  end
132
+
133
+ describe "#attribute?" do
134
+ before :each do
135
+ @object = SpecSupport::HasMetadataTester.new
136
+ @metadata = @object.metadata!
137
+ end
138
+
139
+ context "untyped field" do
140
+ it "should return true if the string is not blank" do
141
+ @metadata.data = { untyped: 'foo' }
142
+ @object.untyped?.should be_true
143
+ end
144
+
145
+ it "should return false if the string is blank" do
146
+ @metadata.data = { untyped: ' ' }
147
+ @object.untyped?.should be_false
148
+
149
+ @metadata.data = { untyped: '' }
150
+ @object.untyped?.should be_false
151
+ end
152
+ end
153
+
154
+ context "numeric field" do
155
+ it "should return true if the number is not zero" do
156
+ @metadata.data = { number: 4 }
157
+ @object.number?.should be_true
158
+ end
159
+
160
+ it "should return false if the number is zero" do
161
+ @metadata.data = { number: 0 }
162
+ @object.number?.should be_false
163
+ end
164
+ end
165
+
166
+ context "typed, non-numeric field" do
167
+ it "should return true if the string is not blank" do
168
+ @metadata.data = { can_be_nil: Date.today }
169
+ @object.can_be_nil?.should be_true
170
+ end
171
+
172
+ it "should return false if the string is blank" do
173
+ @metadata.data = { can_be_nil: nil }
174
+ @object.can_be_nil?.should be_false
175
+ end
176
+ end
177
+ end
134
178
  end
135
179
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 1
8
- - 0
9
- version: 1.1.0
8
+ - 1
9
+ version: 1.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Tim Morgan
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-17 00:00:00 -08:00
17
+ date: 2010-11-21 00:00:00 -08:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency