langalex-couch_potato 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.md ADDED
@@ -0,0 +1,12 @@
1
+ ## Changes
2
+
3
+ ### 0.2.9
4
+
5
+ * allow to overwrite attribute accessor of properties and use super to call the original accessors
6
+ * allow read access to attributes that are present in the Couchdb document but not defined as properties
7
+ * support default values for properties via the :default parameter
8
+ * support attachments via the _attachments property
9
+ * support for namespaces models
10
+ * removed belongs_to macro for now
11
+ * removed CouchPotato::Config.database_server, just set CouchPotato::Config.database_name to the full url if you are not using localhost:5984
12
+ * Ruby 1.9 was broken and is now working again
data/README.md CHANGED
@@ -35,11 +35,11 @@ Alternatively you can download or clone the source repository and then require l
35
35
 
36
36
  You MUST specificy the name of the database:
37
37
 
38
- CouchPotato::Config.database_name = 'name of the db'
38
+ CouchPotato::Config.database_name = 'name_of_the_db'
39
39
 
40
- The server URL will default to http://localhost:5984/ unless specified with:
40
+ The server URL will default to http://localhost:5984/ unless specified:
41
41
 
42
- CouchPotato::Config.database_server = "http://example.com:5984/"
42
+ CouchPotato::Config.database_name = "http://example.com:5984/name_of_the_db"
43
43
 
44
44
  #### Using with Rails
45
45
 
@@ -88,6 +88,14 @@ Properties can be of any type:
88
88
  property :address, :type => Address
89
89
  end
90
90
 
91
+ Properties can have a default value
92
+
93
+ class User
94
+ include CouchPotato::Persistence
95
+
96
+ property :active, :default => true
97
+ end
98
+
91
99
  Now you can save your objects. All database operations are encapsulated in the CouchPotato::Database class. This separates your domain logic from the database access logic which makes it easier to write tests and also keeps you models smaller and cleaner.
92
100
 
93
101
  user = User.new :name => 'joe'
@@ -237,6 +245,22 @@ Supported callbacks are: :before_validation, :before_validation_on_create, :befo
237
245
 
238
246
  If you need access to the database in a callback: Couch Potato automatically assigns a database instance to the model before saving and when loading. It is available as _database_ accessor from within your model instance.
239
247
 
248
+ #### Attachments
249
+
250
+ There is basic attachment support: if you want to store any attachments set that _attachments attribute of a model before saving like this:
251
+
252
+ class User
253
+ include CouchPotato::Persistence
254
+ end
255
+
256
+ user = User.new
257
+ user._attachments = {'photo' => {'data' => '[image byte data]', 'content_type' => 'image/png'}}
258
+
259
+ When saving this object an attachment with the name _photo_ will be uploaded into CouchDB. It will be available under the url of the user object + _/photo_. When loading the user at a later time you still have access to the _content_type_ and additionally to the _length_ of the attachment:
260
+
261
+ user_reloaded = CouchPotato.database.load user.id
262
+ user_reloaded._attachments['photo'] # => {'content_type' => 'image/png', 'length' => 37861}
263
+
240
264
  #### Testing
241
265
 
242
266
  To make testing easier and faster database logic has been put into its own class, which you can replace and stub out in whatever way you want:
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :minor: 2
3
- :patch: 8
4
2
  :major: 0
3
+ :minor: 2
4
+ :patch: 9
data/lib/couch_potato.rb CHANGED
@@ -7,7 +7,7 @@ require 'ostruct'
7
7
 
8
8
 
9
9
  module CouchPotato
10
- Config = OpenStruct.new
10
+ Config = Struct.new(:database_name).new
11
11
 
12
12
  # Returns a database instance which you can then use to create objects and query views. You have to set the CouchPotato::Config.database_name before this works.
13
13
  def self.database
@@ -23,10 +23,10 @@ module CouchPotato
23
23
 
24
24
  def self.full_url_to_database
25
25
  raise('No Database configured. Set CouchPotato::Config.database_name') unless CouchPotato::Config.database_name
26
- if CouchPotato::Config.database_server
27
- return "#{CouchPotato::Config.database_server}#{CouchPotato::Config.database_name}"
26
+ if CouchPotato::Config.database_name[0,7] == 'http://'
27
+ CouchPotato::Config.database_name
28
28
  else
29
- return "http://127.0.0.1:5984/#{CouchPotato::Config.database_name}"
29
+ "http://127.0.0.1:5984/#{CouchPotato::Config.database_name}"
30
30
  end
31
31
  end
32
32
  end
@@ -1,24 +1,24 @@
1
1
  module CouchPotato
2
2
  class Database
3
-
3
+
4
4
  class ValidationsFailedError < ::StandardError; end
5
-
5
+
6
6
  def initialize(couchrest_database)
7
7
  @database = couchrest_database
8
8
  begin
9
- couchrest_database.info
9
+ couchrest_database.info
10
10
  rescue RestClient::ResourceNotFound
11
11
  raise "Database '#{couchrest_database.name}' does not exist."
12
12
  end
13
13
  end
14
-
14
+
15
15
  def view(spec)
16
16
  results = CouchPotato::View::ViewQuery.new(database,
17
17
  spec.design_document, spec.view_name, spec.map_function,
18
18
  spec.reduce_function).query_view!(spec.view_parameters)
19
19
  spec.process_results results
20
20
  end
21
-
21
+
22
22
  def save_document(document)
23
23
  return true unless document.dirty?
24
24
  if document.new?
@@ -28,12 +28,12 @@ module CouchPotato
28
28
  end
29
29
  end
30
30
  alias_method :save, :save_document
31
-
31
+
32
32
  def save_document!(document)
33
33
  save_document(document) || raise(ValidationsFailedError.new(document.errors.full_messages))
34
34
  end
35
35
  alias_method :save!, :save_document!
36
-
36
+
37
37
  def destroy_document(document)
38
38
  document.run_callbacks :before_destroy
39
39
  document._deleted = true
@@ -43,12 +43,13 @@ module CouchPotato
43
43
  document._rev = nil
44
44
  end
45
45
  alias_method :destroy, :destroy_document
46
-
46
+
47
47
  def load_document(id)
48
48
  raise "Can't load a document without an id (got nil)" if id.nil?
49
49
  begin
50
50
  json = database.get(id)
51
- instance = Class.const_get(json['ruby_class']).json_create json
51
+ klass = json['ruby_class'].split('::').inject(Class){|scope, const| scope.const_get(const)}
52
+ instance = klass.json_create json
52
53
  instance.database = self
53
54
  instance
54
55
  rescue(RestClient::ResourceNotFound)
@@ -56,13 +57,19 @@ module CouchPotato
56
57
  end
57
58
  end
58
59
  alias_method :load, :load_document
59
-
60
+
60
61
  def inspect
61
62
  "#<CouchPotato::Database>"
62
63
  end
63
-
64
+
64
65
  private
65
-
66
+
67
+ def clean_hash(hash)
68
+ hash.each do |k,v|
69
+ hash.delete k unless v
70
+ end
71
+ end
72
+
66
73
  def create_document(document)
67
74
  document.database = self
68
75
  document.run_callbacks :before_validation_on_save
@@ -70,30 +77,30 @@ module CouchPotato
70
77
  return unless document.valid?
71
78
  document.run_callbacks :before_save
72
79
  document.run_callbacks :before_create
73
- res = database.save_doc document.to_hash
80
+ res = database.save_doc clean_hash(document.to_hash)
74
81
  document._rev = res['rev']
75
82
  document._id = res['id']
76
83
  document.run_callbacks :after_save
77
84
  document.run_callbacks :after_create
78
85
  true
79
86
  end
80
-
87
+
81
88
  def update_document(document)
82
89
  document.run_callbacks :before_validation_on_save
83
90
  document.run_callbacks :before_validation_on_update
84
91
  return unless document.valid?
85
92
  document.run_callbacks :before_save
86
93
  document.run_callbacks :before_update
87
- res = database.save_doc document.to_hash
94
+ res = database.save_doc clean_hash(document.to_hash)
88
95
  document._rev = res['rev']
89
96
  document.run_callbacks :after_save
90
97
  document.run_callbacks :after_update
91
98
  true
92
99
  end
93
-
100
+
94
101
  def database
95
102
  @database
96
103
  end
97
-
104
+
98
105
  end
99
106
  end
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + '/persistence/magic_timestamps'
5
5
  require File.dirname(__FILE__) + '/persistence/callbacks'
6
6
  require File.dirname(__FILE__) + '/persistence/json'
7
7
  require File.dirname(__FILE__) + '/persistence/dirty_attributes'
8
+ require File.dirname(__FILE__) + '/persistence/ghost_attributes'
9
+ require File.dirname(__FILE__) + '/persistence/attachments'
8
10
  require File.dirname(__FILE__) + '/persistence/validation'
9
11
  require File.dirname(__FILE__) + '/view/custom_views'
10
12
  require File.dirname(__FILE__) + '/view/view_query'
@@ -15,10 +17,10 @@ module CouchPotato
15
17
 
16
18
  def self.included(base)
17
19
  base.send :include, Properties, Callbacks, Validation, Json, CouchPotato::View::CustomViews
18
- base.send :include, DirtyAttributes
20
+ base.send :include, DirtyAttributes, GhostAttributes, Attachments
19
21
  base.send :include, MagicTimestamps
20
22
  base.class_eval do
21
- attr_accessor :_id, :_rev, :_attachments, :_deleted, :database
23
+ attr_accessor :_id, :_rev, :_deleted, :database
22
24
  alias_method :id, :_id
23
25
  end
24
26
  end
@@ -0,0 +1,26 @@
1
+ module CouchPotato
2
+ module Attachments
3
+ def self.included(base)
4
+ base.class_eval do
5
+ attr_accessor :_attachments
6
+ base.extend ClassMethods
7
+ end
8
+ end
9
+
10
+ def to_hash
11
+ if _attachments
12
+ super.merge('_attachments' => _attachments)
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ module ClassMethods
19
+ def json_create(json)
20
+ instance = super
21
+ instance._attachments = json['_attachments'] if json
22
+ instance
23
+ end
24
+ end
25
+ end
26
+ end
@@ -5,6 +5,11 @@ module CouchPotato
5
5
  def self.included(base)
6
6
  base.class_eval do
7
7
  after_save :reset_dirty_attributes
8
+
9
+ def initialize(attributes = {})
10
+ super
11
+ assign_attribute_copies_for_dirty_tracking
12
+ end
8
13
  end
9
14
  end
10
15
 
@@ -17,11 +22,28 @@ module CouchPotato
17
22
 
18
23
  private
19
24
 
25
+ def assign_attribute_copies_for_dirty_tracking
26
+ attributes.each do |name, value|
27
+ self.instance_variable_set("@#{name}_was", clone_attribute(value))
28
+ end if attributes
29
+ end
30
+
20
31
  def reset_dirty_attributes
21
32
  self.class.properties.each do |property|
22
- instance_variable_set("@#{property.name}_was", send(property.name))
33
+ instance_variable_set("@#{property.name}_was", clone_attribute(send(property.name)))
34
+ end
35
+ end
36
+
37
+ def clone_attribute(value)
38
+ if [Fixnum, Symbol, TrueClass, FalseClass, NilClass, Float].include?(value.class)
39
+ value
40
+ elsif [Hash, Array].include?(value.class)
41
+ #Deep clone
42
+ Marshal::load(Marshal::dump(value))
43
+ else
44
+ value.clone
23
45
  end
24
46
  end
25
47
  end
26
48
  end
27
- end
49
+ end
@@ -0,0 +1,22 @@
1
+ module CouchPotato
2
+ module GhostAttributes
3
+ def self.included(base)
4
+ base.class_eval do
5
+ attr_accessor :_document
6
+ def self.json_create(json)
7
+ instance = super
8
+ instance._document = json if json
9
+ instance
10
+ end
11
+
12
+ def method_missing(name, *args)
13
+ if(value = _document[name.to_s])
14
+ value
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,4 @@
1
1
  require File.dirname(__FILE__) + '/simple_property'
2
- require File.dirname(__FILE__) + '/belongs_to_property'
3
2
 
4
3
  module CouchPotato
5
4
  module Persistence
@@ -13,7 +12,7 @@ module CouchPotato
13
12
  end
14
13
  end
15
14
  end
16
-
15
+
17
16
  module ClassMethods
18
17
  # returns all the property names of a model class that have been defined using the #property method
19
18
  #
@@ -47,10 +46,6 @@ module CouchPotato
47
46
  properties << (clazz || SimpleProperty).new(self, name, options)
48
47
  end
49
48
 
50
- def belongs_to(name) #:nodoc:
51
- property name, :class => BelongsToProperty
52
- end
53
-
54
49
  end
55
50
  end
56
51
  end
@@ -6,55 +6,18 @@ module CouchPotato
6
6
  def initialize(owner_clazz, name, options = {})
7
7
  self.name = name
8
8
  self.type = options[:type]
9
- owner_clazz.class_eval do
10
- attr_reader name, "#{name}_was"
11
-
12
- def initialize(attributes = {})
13
- super attributes
14
- assign_attribute_copies_for_dirty_tracking
15
- end
16
-
17
- def assign_attribute_copies_for_dirty_tracking
18
- attributes.each do |name, value|
19
- self.instance_variable_set("@#{name}_was", clone_attribute(value))
20
- end if attributes
21
- end
22
- private :assign_attribute_copies_for_dirty_tracking
23
-
24
- def clone_attribute(value)
25
- if [Fixnum, Symbol, TrueClass, FalseClass, NilClass, Float].include?(value.class)
26
- value
27
- else
28
- value.clone
29
- end
30
- end
31
-
32
- define_method "#{name}=" do |value|
33
- self.instance_variable_set("@#{name}", value)
34
- end
35
-
36
- define_method "#{name}?" do
37
- !self.send(name).nil? && !self.send(name).try(:blank?)
38
- end
39
-
40
- define_method "#{name}_changed?" do
41
- !self.instance_variable_get("@#{name}_not_changed") && self.send(name) != self.send("#{name}_was")
42
- end
43
-
44
- define_method "#{name}_not_changed" do
45
- self.instance_variable_set("@#{name}_not_changed", true)
46
- end
47
- end
9
+
10
+ define_accessors accessors_module_for(owner_clazz), name, options
48
11
  end
49
12
 
50
13
  def build(object, json)
51
14
  value = json[name.to_s] || json[name.to_sym]
52
- typecasted_value = if type
15
+ typecast_value = if type
53
16
  type.json_create value
54
17
  else
55
18
  value
56
19
  end
57
- object.send "#{name}=", typecasted_value
20
+ object.send "#{name}=", typecast_value
58
21
  end
59
22
 
60
23
  def dirty?(object)
@@ -72,6 +35,49 @@ module CouchPotato
72
35
  def serialize(json, object)
73
36
  json[name] = object.send name
74
37
  end
38
+
39
+ private
40
+
41
+ def accessors_module_for(clazz)
42
+ unless clazz.const_defined?('AccessorMethods')
43
+ accessors_module = clazz.const_set('AccessorMethods', Module.new)
44
+ clazz.send(:include, accessors_module)
45
+ end
46
+ clazz.const_get('AccessorMethods')
47
+ end
48
+
49
+ def define_accessors(base, name, options)
50
+ base.class_eval do
51
+ attr_reader "#{name}_was"
52
+
53
+ define_method "#{name}" do
54
+ value = self.instance_variable_get("@#{name}")
55
+ if value.blank? && options[:default]
56
+ default = clone_attribute(options[:default])
57
+ self.instance_variable_set("@#{name}", default)
58
+ default
59
+ else
60
+ value
61
+ end
62
+ end
63
+
64
+ define_method "#{name}=" do |value|
65
+ self.instance_variable_set("@#{name}", value)
66
+ end
67
+
68
+ define_method "#{name}?" do
69
+ !self.send(name).nil? && !self.send(name).try(:blank?)
70
+ end
71
+
72
+ define_method "#{name}_changed?" do
73
+ !self.instance_variable_get("@#{name}_not_changed") && self.send(name) != self.send("#{name}_was")
74
+ end
75
+
76
+ define_method "#{name}_not_changed" do
77
+ self.instance_variable_set("@#{name}_not_changed", true)
78
+ end
79
+ end
80
+ end
75
81
  end
76
82
  end
77
- end
83
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe CouchPotato, 'attachments' do
4
+ it "should persist an attachment" do
5
+ comment = Comment.new :title => 'nil'
6
+ comment._attachments = {'body' => {'data' => 'a useful comment', 'content_type' => 'text/plain'}}
7
+ CouchPotato.database.save! comment
8
+ CouchPotato.couchrest_database.fetch_attachment(comment.to_hash, 'body').to_s.should == 'a useful comment'
9
+ end
10
+
11
+ it "should give me information about the attachments of a document" do
12
+ comment = Comment.new :title => 'nil'
13
+ comment._attachments = {'body' => {'data' => 'a useful comment', 'content_type' => 'text/plain'}}
14
+ CouchPotato.database.save! comment
15
+ comment_reloaded = CouchPotato.database.load comment.id
16
+ comment_reloaded._attachments.should == {"body" => {"content_type" => "text/plain", "stub" => true, "length" => 16}}
17
+ end
18
+
19
+ end
@@ -0,0 +1,34 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ class Test
4
+ include CouchPotato::Persistence
5
+
6
+ property :test, :default => 'Test value'
7
+ property :complex, :default => []
8
+ end
9
+
10
+ describe 'default properties' do
11
+ before(:all) do
12
+ recreate_db
13
+ end
14
+
15
+ it "should use the default value if nothing is supplied" do
16
+ t = Test.new
17
+
18
+ t.test.should == 'Test value'
19
+ end
20
+
21
+ it "should persist the default value if nothing is supplied" do
22
+ t = Test.new
23
+ CouchPotato.database.save_document! t
24
+
25
+ t = CouchPotato.database.load_document t.id
26
+ t.test.should == 'Test value'
27
+ end
28
+
29
+ it "should not have the same default for two instances of the object" do
30
+ t = Test.new
31
+ t2 = Test.new
32
+ t.complex.object_id.should_not == t2.complex.object_id
33
+ end
34
+ end
@@ -6,6 +6,16 @@ class Watch
6
6
  include CouchPotato::Persistence
7
7
 
8
8
  property :time, :type => Time
9
+ property :overwritten_read
10
+ property :overwritten_write
11
+
12
+ def overwritten_read
13
+ super.to_s
14
+ end
15
+
16
+ def overwritten_write=(value)
17
+ super value.to_s
18
+ end
9
19
  end
10
20
 
11
21
 
@@ -14,8 +24,16 @@ describe 'properties' do
14
24
  recreate_db
15
25
  end
16
26
 
27
+ it "should allow me to overwrite read accessor and call super" do
28
+ Watch.new(:overwritten_read => 1).overwritten_read.should == '1'
29
+ end
30
+
31
+ it "should allow me to overwrite write accessor and call super" do
32
+ Watch.new(:overwritten_write => 1).overwritten_write.should == '1'
33
+ end
34
+
17
35
  it "should return the property names" do
18
- Comment.property_names.should == [:created_at, :updated_at, :title, :commenter]
36
+ Comment.property_names.should == [:created_at, :updated_at, :title]
19
37
  end
20
38
 
21
39
  it "should persist a string" do
data/spec/spec_helper.rb CHANGED
@@ -6,7 +6,6 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
6
6
  require 'couch_potato'
7
7
 
8
8
  CouchPotato::Config.database_name = 'couch_potato_test'
9
- CouchPotato::Config.database_server = 'http://127.0.0.1:5984/'
10
9
 
11
10
 
12
11
  class Comment
@@ -15,7 +14,6 @@ class Comment
15
14
  validates_presence_of :title
16
15
 
17
16
  property :title
18
- belongs_to :commenter
19
17
  end
20
18
 
21
19
  def recreate_db
@@ -21,6 +21,21 @@ describe "attributes" do
21
21
  plant.attributes.should == {:leaf_count => 1, :created_at => nil, :updated_at => nil}
22
22
  end
23
23
  end
24
+
25
+ # useful when loading models from custom views
26
+ describe "accessing non-property attributes" do
27
+ it "should allow me to access attributes that are in the couchdb document " do
28
+ plant = Plant.json_create({"ruby_class" => "Plant", "color" => "red", "leaf_count" => 1})
29
+ plant.color.should == 'red'
30
+ end
31
+
32
+ it "should raise a no method error when trying to read attributes that are not in the document" do
33
+ plant = Plant.json_create({"ruby_class" => "Plant", "leaf_count" => 1})
34
+ lambda do
35
+ plant.length
36
+ end.should raise_error(NoMethodError)
37
+ end
38
+ end
24
39
 
25
40
  end
26
41
 
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe CouchPotato, 'full_url_to_database' do
4
+ before(:each) do
5
+ @original_database_name = CouchPotato::Config.database_name
6
+ end
7
+ after(:each) do
8
+ CouchPotato::Config.database_name = @original_database_name
9
+ end
10
+
11
+ it "should add the default localhost and port if only a name is set" do
12
+ CouchPotato::Config.database_name = 'test'
13
+ CouchPotato.full_url_to_database.should == 'http://127.0.0.1:5984/test'
14
+ end
15
+
16
+ it "should return the set url" do
17
+ CouchPotato::Config.database_name = 'http://db.local/test'
18
+ CouchPotato.full_url_to_database.should == 'http://db.local/test'
19
+ end
20
+ end
@@ -3,6 +3,13 @@ require File.dirname(__FILE__) + '/../spec_helper'
3
3
  class DbTestUser
4
4
  end
5
5
 
6
+ # namespaced model
7
+ module Parent
8
+ class Child
9
+ include CouchPotato::Persistence
10
+ end
11
+ end
12
+
6
13
  describe CouchPotato::Database, 'new' do
7
14
  it "should raise an exception if the database doesn't exist" do
8
15
  lambda {
@@ -18,7 +25,7 @@ describe CouchPotato::Database, 'load' do
18
25
  db.load nil
19
26
  }.should raise_error("Can't load a document without an id (got nil)")
20
27
  end
21
-
28
+
22
29
  it "should set itself on the model" do
23
30
  user = mock 'user'
24
31
  DbTestUser.stub!(:new).and_return(user)
@@ -26,6 +33,11 @@ describe CouchPotato::Database, 'load' do
26
33
  user.should_receive(:database=).with(db)
27
34
  db.load '1'
28
35
  end
36
+
37
+ it "should load namespaced models" do
38
+ db = CouchPotato::Database.new(stub('couchrest db', :info => nil, :get => {'ruby_class' => 'Parent::Child'}))
39
+ db.load('1').class.should == Parent::Child
40
+ end
29
41
  end
30
42
 
31
43
  describe CouchPotato::Database, 'save_document' do
@@ -33,6 +33,24 @@ describe 'dirty attribute tracking' do
33
33
  @couchrest_db.should_receive(:save_doc)
34
34
  @db.save_document(plate)
35
35
  end
36
+
37
+ it "should correctly track dirty hashes (deep clone)" do
38
+ plate = Plate.new :food => {:veggies => ['carrots', 'peas']}
39
+ @db.save_document(plate)
40
+ plate.food[:veggies] << 'beans'
41
+ @couchrest_db.should_receive(:save_doc)
42
+ @db.save_document(plate)
43
+ end
44
+
45
+ it "should correctly track dirty hashes (deep clone) after a save" do
46
+ plate = Plate.new :food => {:veggies => ['carrots', 'peas']}
47
+ @db.save_document(plate)
48
+ plate.food[:veggies] << 'beans'
49
+ @db.save_document(plate)
50
+ plate.food[:veggies] << 'cauliflower'
51
+ @couchrest_db.should_receive(:save_doc)
52
+ @db.save_document(plate)
53
+ end
36
54
  end
37
55
 
38
56
  describe "newly created object" do
@@ -110,4 +128,4 @@ describe 'dirty attribute tracking' do
110
128
  end
111
129
  end
112
130
 
113
- end
131
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: langalex-couch_potato
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.9
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-07-01 00:00:00 -07:00
12
+ date: 2009-09-18 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -51,6 +51,7 @@ extensions: []
51
51
  extra_rdoc_files:
52
52
  - README.md
53
53
  files:
54
+ - CHANGES.md
54
55
  - MIT-LICENSE.txt
55
56
  - README.md
56
57
  - VERSION.yml
@@ -63,9 +64,10 @@ files:
63
64
  - lib/couch_potato.rb
64
65
  - lib/couch_potato/database.rb
65
66
  - lib/couch_potato/persistence.rb
66
- - lib/couch_potato/persistence/belongs_to_property.rb
67
+ - lib/couch_potato/persistence/attachments.rb
67
68
  - lib/couch_potato/persistence/callbacks.rb
68
69
  - lib/couch_potato/persistence/dirty_attributes.rb
70
+ - lib/couch_potato/persistence/ghost_attributes.rb
69
71
  - lib/couch_potato/persistence/json.rb
70
72
  - lib/couch_potato/persistence/magic_timestamps.rb
71
73
  - lib/couch_potato/persistence/properties.rb
@@ -79,9 +81,11 @@ files:
79
81
  - lib/couch_potato/view/raw_view_spec.rb
80
82
  - lib/couch_potato/view/view_query.rb
81
83
  - rails/init.rb
84
+ - spec/attachments_spec.rb
82
85
  - spec/callbacks_spec.rb
83
86
  - spec/create_spec.rb
84
87
  - spec/custom_view_spec.rb
88
+ - spec/default_property_spec.rb
85
89
  - spec/destroy_spec.rb
86
90
  - spec/fixtures/address.rb
87
91
  - spec/fixtures/person.rb
@@ -90,6 +94,7 @@ files:
90
94
  - spec/spec_helper.rb
91
95
  - spec/unit/attributes_spec.rb
92
96
  - spec/unit/callbacks_spec.rb
97
+ - spec/unit/couch_potato_spec.rb
93
98
  - spec/unit/create_spec.rb
94
99
  - spec/unit/customs_views_spec.rb
95
100
  - spec/unit/database_spec.rb
@@ -97,8 +102,9 @@ files:
97
102
  - spec/unit/string_spec.rb
98
103
  - spec/unit/view_query_spec.rb
99
104
  - spec/update_spec.rb
100
- has_rdoc: true
105
+ has_rdoc: false
101
106
  homepage: http://github.com/langalex/couch_potato
107
+ licenses:
102
108
  post_install_message:
103
109
  rdoc_options:
104
110
  - --charset=UTF-8
@@ -119,14 +125,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
125
  requirements: []
120
126
 
121
127
  rubyforge_project:
122
- rubygems_version: 1.2.0
128
+ rubygems_version: 1.3.5
123
129
  signing_key:
124
- specification_version: 2
130
+ specification_version: 3
125
131
  summary: Ruby persistence layer for CouchDB
126
132
  test_files:
133
+ - spec/attachments_spec.rb
127
134
  - spec/callbacks_spec.rb
128
135
  - spec/create_spec.rb
129
136
  - spec/custom_view_spec.rb
137
+ - spec/default_property_spec.rb
130
138
  - spec/destroy_spec.rb
131
139
  - spec/fixtures/address.rb
132
140
  - spec/fixtures/person.rb
@@ -134,6 +142,7 @@ test_files:
134
142
  - spec/spec_helper.rb
135
143
  - spec/unit/attributes_spec.rb
136
144
  - spec/unit/callbacks_spec.rb
145
+ - spec/unit/couch_potato_spec.rb
137
146
  - spec/unit/create_spec.rb
138
147
  - spec/unit/customs_views_spec.rb
139
148
  - spec/unit/database_spec.rb
@@ -1,58 +0,0 @@
1
- module CouchPotato
2
- module Persistence
3
- class BelongsToProperty #:nodoc:
4
- attr_accessor :name
5
-
6
- def initialize(owner_clazz, name, options = {})
7
- self.name = name
8
- accessors = <<-ACCESSORS
9
- def #{name}
10
- return @#{name} if instance_variable_defined?(:@#{name})
11
- @#{name} = @#{name}_id ? #{item_class_name}.find(@#{name}_id) : nil
12
- end
13
-
14
- def #{name}=(value)
15
- @#{name} = value
16
- if value.nil?
17
- @#{name}_id = nil
18
- else
19
- @#{name}_id = value.id
20
- end
21
- end
22
-
23
- def #{name}_id=(id)
24
- remove_instance_variable(:@#{name}) if instance_variable_defined?(:@#{name})
25
- @#{name}_id = id
26
- end
27
- ACCESSORS
28
- owner_clazz.class_eval accessors
29
- owner_clazz.send :attr_reader, "#{name}_id"
30
- end
31
-
32
- def save(object)
33
-
34
- end
35
-
36
- def dirty?(object)
37
- false
38
- end
39
-
40
- def destroy(object)
41
-
42
- end
43
-
44
- def build(object, json)
45
- object.send "#{name}_id=", json["#{name}_id"]
46
- end
47
-
48
- def serialize(json, object)
49
- json["#{name}_id"] = object.send("#{name}_id") if object.send("#{name}_id")
50
- end
51
-
52
- def item_class_name
53
- @name.to_s.camelize
54
- end
55
-
56
- end
57
- end
58
- end