couch_potato 0.2.16 → 0.2.17

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## Changes
2
2
 
3
+ ### 0.2.17
4
+ * fixed nil attributes were omitted in json (jweiss, mattmatt)
5
+ * support for properties of type Fixnum (langalex)
6
+
3
7
  ### 0.2.16
4
8
  * fixed problem with classes being not loaded in rails development mode (langalex)
5
9
  * fixed persist boolean false value (bernd)
data/README.md CHANGED
@@ -79,15 +79,27 @@ If you want to store any properties you have to declare them:
79
79
  property :name
80
80
  end
81
81
 
82
- Properties can be of any type:
82
+ Properties can be typed:
83
83
 
84
84
  class User
85
85
  include CouchPotato::Persistence
86
86
 
87
87
  property :address, :type => Address
88
88
  end
89
+
90
+ In this case Address also implements CouchPotato::Persistence which means its JSON representation will be added to the user document.
91
+ Couch Potato also has support for the basic types (right now only Fixnum is supported):
92
+
93
+ class User
94
+ include CouchPotato::Persistence
95
+
96
+ property :age, :type => Fixnum
97
+ end
98
+
99
+ With this in place when you set the user's age as a String (e.g. using an hTML form) it will be converted into a Fixnum automatically.
100
+
89
101
 
90
- Properties can have a default value
102
+ Properties can have a default value:
91
103
 
92
104
  class User
93
105
  include CouchPotato::Persistence
@@ -1,4 +1,5 @@
1
1
  ---
2
- :major: 0
2
+ :build:
3
3
  :minor: 2
4
- :patch: 16
4
+ :patch: 17
5
+ :major: 0
@@ -63,12 +63,6 @@ module CouchPotato
63
63
 
64
64
  private
65
65
 
66
- def clean_hash(hash)
67
- hash.each do |k,v|
68
- hash.delete k if v.nil?
69
- end
70
- end
71
-
72
66
  def create_document(document, validate)
73
67
  document.database = self
74
68
 
@@ -81,7 +75,7 @@ module CouchPotato
81
75
 
82
76
  document.run_callbacks :before_save
83
77
  document.run_callbacks :before_create
84
- res = database.save_doc clean_hash(document.to_hash)
78
+ res = database.save_doc document.to_hash
85
79
  document._rev = res['rev']
86
80
  document._id = res['id']
87
81
  document.run_callbacks :after_save
@@ -99,7 +93,7 @@ module CouchPotato
99
93
 
100
94
  document.run_callbacks :before_save
101
95
  document.run_callbacks :before_update
102
- res = database.save_doc clean_hash(document.to_hash)
96
+ res = database.save_doc document.to_hash
103
97
  document._rev = res['rev']
104
98
  document.run_callbacks :after_save
105
99
  document.run_callbacks :after_update
@@ -8,6 +8,7 @@ require File.dirname(__FILE__) + '/persistence/dirty_attributes'
8
8
  require File.dirname(__FILE__) + '/persistence/ghost_attributes'
9
9
  require File.dirname(__FILE__) + '/persistence/attachments'
10
10
  require File.dirname(__FILE__) + '/persistence/validation'
11
+ require File.dirname(__FILE__) + '/persistence/type_caster'
11
12
  require File.dirname(__FILE__) + '/view/custom_views'
12
13
  require File.dirname(__FILE__) + '/view/view_query'
13
14
 
@@ -42,6 +42,10 @@ module CouchPotato
42
42
  end
43
43
  end
44
44
 
45
+ def type_caster
46
+ @type_caster ||= TypeCaster.new
47
+ end
48
+
45
49
  module ClassMethods
46
50
  # returns all the property names of a model class that have been defined using the #property method
47
51
  #
@@ -6,18 +6,14 @@ module CouchPotato
6
6
  def initialize(owner_clazz, name, options = {})
7
7
  self.name = name
8
8
  self.type = options[:type]
9
+ @type_caster = TypeCaster.new
9
10
 
10
11
  define_accessors accessors_module_for(owner_clazz), name, options
11
12
  end
12
13
 
13
14
  def build(object, json)
14
15
  value = json[name.to_s].nil? ? json[name.to_sym] : json[name.to_s]
15
- typecast_value = if type && !value.instance_of?(type)
16
- type.json_create value
17
- else
18
- value
19
- end
20
- object.send "#{name}=", typecast_value
16
+ object.send "#{name}=", @type_caster.cast(value, type)
21
17
  end
22
18
 
23
19
  def dirty?(object)
@@ -62,7 +58,7 @@ module CouchPotato
62
58
  end
63
59
 
64
60
  define_method "#{name}=" do |value|
65
- self.instance_variable_set("@#{name}", value)
61
+ self.instance_variable_set("@#{name}", type_caster.cast(value, options[:type]))
66
62
  end
67
63
 
68
64
  define_method "#{name}?" do
@@ -0,0 +1,17 @@
1
+ module CouchPotato
2
+ module Persistence
3
+ class TypeCaster
4
+ def cast(value, type)
5
+ if type && !value.instance_of?(type)
6
+ if type == Fixnum
7
+ value.to_s.scan(/\d/).join.to_i unless value.nil?
8
+ else
9
+ type.json_create value
10
+ end
11
+ else
12
+ value
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -122,6 +122,17 @@ describe 'properties' do
122
122
  p = CouchPotato.database.load_document p.id
123
123
  p.ship_address.should be_nil
124
124
  end
125
+
126
+ it "should actually pass the null value down in the JSON document " do
127
+ p = Person.new
128
+ p.ship_address = nil
129
+ db = mock(:database)
130
+ db.should_receive(:save_doc).with do |attributes|
131
+ attributes.has_key?(:ship_address).should == true
132
+ end.and_return({})
133
+ CouchPotato.database.stub(:database).and_return(db)
134
+ CouchPotato.database.save_document! p
135
+ end
125
136
 
126
137
  it "should persist false for a false" do
127
138
  p = Person.new
@@ -3,6 +3,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
3
3
  class Plant
4
4
  include CouchPotato::Persistence
5
5
  property :leaf_count
6
+ property :typed_leaf_count, :type => Fixnum
6
7
  end
7
8
 
8
9
  describe "attributes" do
@@ -18,7 +19,7 @@ describe "attributes" do
18
19
  describe "attributes" do
19
20
  it "should return the attributes" do
20
21
  plant = Plant.new(:leaf_count => 1)
21
- plant.attributes.should == {:leaf_count => 1, :created_at => nil, :updated_at => nil}
22
+ plant.attributes.should == {:leaf_count => 1, :created_at => nil, :updated_at => nil, :typed_leaf_count => nil}
22
23
  end
23
24
  end
24
25
 
@@ -44,5 +45,38 @@ describe "attributes" do
44
45
  end
45
46
  end
46
47
 
48
+ describe 'typed attributes' do
49
+ describe "fixnum" do
50
+ before(:each) do
51
+ @plant = Plant.new
52
+ end
53
+
54
+ it "should convert a string into a finum" do
55
+ @plant.typed_leaf_count = '4'
56
+ @plant.typed_leaf_count.should == 4
57
+ end
58
+
59
+ it "should leave a fixnum as is" do
60
+ @plant.typed_leaf_count = 4
61
+ @plant.typed_leaf_count.should == 4
62
+ end
63
+
64
+ it "should leave nil as is" do
65
+ @plant.typed_leaf_count = nil
66
+ @plant.typed_leaf_count.should be_nil
67
+ end
68
+
69
+ it "should set the attributes to zero if a string given" do
70
+ @plant.typed_leaf_count = 'x'
71
+ @plant.typed_leaf_count.should == 0
72
+ end
73
+
74
+ it "should parse numbers out of a string" do
75
+ @plant.typed_leaf_count = 'x123'
76
+ @plant.typed_leaf_count.should == 123
77
+ end
78
+
79
+ end
80
+ end
47
81
  end
48
82
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couch_potato
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.16
4
+ version: 0.2.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Lang
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-22 00:00:00 +01:00
12
+ date: 2009-12-02 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -72,6 +72,7 @@ files:
72
72
  - lib/couch_potato/persistence/magic_timestamps.rb
73
73
  - lib/couch_potato/persistence/properties.rb
74
74
  - lib/couch_potato/persistence/simple_property.rb
75
+ - lib/couch_potato/persistence/type_caster.rb
75
76
  - lib/couch_potato/persistence/validation.rb
76
77
  - lib/couch_potato/rspec/matchers.rb
77
78
  - lib/couch_potato/rspec/matchers/map_to_matcher.rb