couch_potato 0.2.16 → 0.2.17

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/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