tableless_model 0.0.5 → 0.0.6
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/README.rdoc
CHANGED
@@ -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,
|
data/lib/tableless_model.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
|
@@ -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
|
-
|
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
|
-
|
192
|
-
|
193
|
-
@instance.options.aaa.must_equal "CCC"
|
194
|
-
@instance.options.bbb.must_equal "DDD"
|
233
|
+
|
234
|
+
instance = TestModel.first
|
195
235
|
|
196
|
-
|
197
|
-
|
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
|
-
-
|
9
|
-
version: 0.0.
|
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-
|
17
|
+
date: 2011-01-12 00:00:00 +00:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|