tableless_model 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -16,7 +16,7 @@ Tableless Model is available as a Rubygem:
16
16
 
17
17
  gem install tableless_model
18
18
 
19
- (current version: 0.0.5)
19
+ (current version: 0.0.6)
20
20
 
21
21
 
22
22
  == Usage
@@ -27,7 +27,8 @@ module Base
27
27
 
28
28
  # if only the column name is given, the tableless model's class is expected to have that name, classified, as class name
29
29
  class_type = column.class == Hash ? column.collect{|k,v| v}.last : column.to_s.classify.constantize
30
-
30
+
31
+
31
32
  # injecting in the parent object a getter and a setter for the
32
33
  # attribute that will store an instance of a tableless model
33
34
  class_eval do
@@ -41,7 +42,12 @@ module Base
41
42
  # model and not just a normal hash or the value of the attribute in the database,
42
43
  # which is plain text
43
44
  define_method column_name.to_s do
44
- class_type.new(read_attribute(column_name.to_sym) || {})
45
+ instance = class_type.new(read_attribute(column_name.to_sym) || {})
46
+
47
+ instance.__owner_object = self
48
+ instance.__serialized_attribute = column_name
49
+
50
+ instance
45
51
  end
46
52
 
47
53
  # Adding setter for the serialized column,
@@ -12,8 +12,12 @@ module ActiveRecord
12
12
  class TablelessModel < Hash
13
13
 
14
14
  extend Tableless::ClassMethods
15
+
15
16
  include Tableless::InstanceMethods
16
- include Validatable
17
+ include Validatable
18
+
19
+
20
+ attr_accessor :__owner_object, :__serialized_attribute
17
21
 
18
22
  #
19
23
  #
@@ -24,6 +28,7 @@ module ActiveRecord
24
28
  #
25
29
  class << self
26
30
  attr_reader :attributes
31
+
27
32
  end
28
33
 
29
34
  end
@@ -46,7 +46,17 @@ module Tableless
46
46
  #
47
47
  def []=(attribute_name, value)
48
48
  raise NoMethodError, "The attribute #{attribute_name} is undefined" unless self.class.attributes.has_key? attribute_name.to_s
49
- super attribute_name.to_s, self.class.cast(attribute_name, value)
49
+
50
+ return_value = super(attribute_name.to_s, self.class.cast(attribute_name, value))
51
+
52
+ if self.__owner_object
53
+ # This makes the tableless model compatible with partial_updates:
54
+ # whenever a property in the tableless model is changed, we force the parent/owner object to a changed state
55
+ # by updating it with a new, updated instance of the tableless model
56
+ self.__owner_object.send "#{self.__serialized_attribute.to_s}=".to_sym, self
57
+ end
58
+
59
+ return_value
50
60
  end
51
61
 
52
62
 
@@ -1,3 +1,3 @@
1
1
  module TablelessModel
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -98,6 +98,22 @@ describe "An instance of TablelessModel" do
98
98
  attribute :typed_test_attribute, :type => :integer
99
99
  end
100
100
  end
101
+
102
+ describe "instance" do
103
+ before do
104
+ @instance = TestClass3.new
105
+ end
106
+
107
+ it "has rw the accessor __owner_object" do
108
+ @instance.must_respond_to "__owner_object"
109
+ @instance.must_respond_to "__owner_object="
110
+ end
111
+
112
+ it "has rw the accessor __serialized_attribute" do
113
+ @instance.must_respond_to "__serialized_attribute"
114
+ @instance.must_respond_to "__serialized_attribute="
115
+ end
116
+ end
101
117
 
102
118
  it "tries to enforce type casting if a type has been specified for an attribute" do
103
119
 
@@ -140,14 +156,13 @@ describe "An instance of TablelessModel" do
140
156
  end
141
157
  end
142
158
 
143
-
144
159
  describe "An ActiveRecord::Base model" do
145
160
  before do
146
161
  class ModelOptions < ActiveRecord::TablelessModel
147
162
  attribute :aaa, :default => 111
148
163
  attribute :bbb, :default => "bbb"
149
164
  end
150
-
165
+
151
166
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
152
167
  ActiveRecord::Base.connection.execute(" create table test_models (options varchar(50)) ")
153
168
 
@@ -155,16 +170,32 @@ describe "An ActiveRecord::Base model" do
155
170
  has_tableless :options => ModelOptions
156
171
  end
157
172
  end
158
-
173
+
159
174
  it "responds to default_value_for, has_tableless" do
160
175
  TestModel.must_respond_to(:has_tableless)
161
176
  end
162
177
 
163
- describe "new instance" do
178
+
179
+ describe "instance" do
164
180
  before do
165
181
  @instance = TestModel.new
166
182
  end
167
183
 
184
+ it "must respond to changed?" do
185
+ @instance.must_respond_to "changed?"
186
+ @instance.changed?.must_equal false
187
+ @instance.changes.must_equal({})
188
+ end
189
+
190
+ it "sets the accessor __owner_object to self in the tableless model instance" do
191
+ @instance.options.__owner_object.must_equal @instance
192
+ end
193
+
194
+ it "sets the accessor __serialized_attribute to the name of its column that stored the tableless model instance, serialized" do
195
+ @instance.options.__serialized_attribute.must_equal :options
196
+ end
197
+
198
+
168
199
  it "has a getter and a setter for :options" do
169
200
  %w(options options=).each{|m| @instance.must_respond_to m }
170
201
  @instance.options.must_be_kind_of ModelOptions
@@ -173,12 +204,12 @@ describe "An ActiveRecord::Base model" do
173
204
  @instance.options.bbb.must_equal "bbb"
174
205
  proc { @instance.options = "test" }.must_raise NoMethodError, "should not accept other values than a hash or ModelOptions instance"
175
206
  end
176
-
207
+
177
208
  describe "setter" do
178
209
  before do
179
210
  @return_value = @instance.send("options=", { :aaa => "CCC", :bbb => "DDD" })
180
211
  end
181
-
212
+
182
213
  it "correctly sets the serialized column" do
183
214
  @return_value.must_be_kind_of ModelOptions
184
215
  %w(aaa bbb).each{|m| @return_value.must_respond_to m}
@@ -186,18 +217,30 @@ describe "An ActiveRecord::Base model" do
186
217
  @instance.options.bbb.must_equal "DDD"
187
218
  end
188
219
 
220
+ it "forces the owner object to a changed state with partial_updates on" do
221
+ @instance.options.aaa = "changed aaa"
222
+ @instance.options.bbb = "changed bbb"
223
+
224
+ @instance.options.aaa.must_equal "changed aaa"
225
+ @instance.changes.keys.include?("options").must_equal true
226
+
227
+ @instance.changes[:options][0].must_equal nil
228
+ @instance.changes[:options][1].must_equal({"aaa"=>"changed aaa", "bbb"=>"changed bbb"})
229
+ end
230
+
189
231
  it "should save the serialized column correctly" do
190
232
  @instance.save!
191
- @instance = TestModel.first
192
-
193
- @instance.options.aaa.must_equal "CCC"
194
- @instance.options.bbb.must_equal "DDD"
233
+
234
+ instance = TestModel.first
195
235
 
196
- # Ensuring the serialize macro is used
197
- @instance.options.must_be_kind_of ModelOptions
236
+ instance.options.aaa.must_equal "CCC"
237
+ instance.options.bbb.must_equal "DDD"
198
238
 
239
+ # Ensuring the serialize macro is used
240
+ instance.options.must_be_kind_of ModelOptions
199
241
  end
200
242
  end
201
243
  end
244
+ end
245
+
202
246
 
203
- end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 5
9
- version: 0.0.5
8
+ - 6
9
+ version: 0.0.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Vito Botta
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-11 00:00:00 +00:00
17
+ date: 2011-01-12 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency