datts_right 0.0.8 → 0.0.9

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.textile CHANGED
@@ -75,20 +75,16 @@ h3. Adding a dynamic attribute to a record
75
75
 
76
76
  pre. @user = User.create :name => "Roland Deschain"
77
77
  @user.add_dynamic_attribute(:age, "integer")
78
- @user.age = 820
78
+ @user.write_dynamic_attribute :age, 820
79
79
  @user.save
80
80
 
81
- h3. @instance.dynamic_attributes
82
-
83
- Given the @user above, this prints out the dynamic_attributes just like AR::Base#attributes prints out the attributes
84
-
85
- pre. @user.dynamic_attributes # {:name => 820}
86
-
87
81
  h3. @instance.dynamic_columns
88
82
 
89
83
  However, dynamic_attributes doesn't give us much information. What if we want to find out the list of dynamic attributes already available?
90
84
 
91
- pre. @user.dynamic_columns # {:age => {:object_type => "integer", :value => 820}}
85
+ pre. @user.dynamic_attribute_details(:age) # Returns a dynamic attribute record, where you can access the following:
86
+ @user.dynamic_attribute_details(:age).object_type # "integer"
87
+ @user.dynamic_attribute_details(:age).value # 820
92
88
 
93
89
  h3. dynamic_attribute?(:some_attribute)
94
90
 
@@ -109,7 +105,7 @@ The dynamic attributes are only actually saved when save is called on the record
109
105
 
110
106
  pre. @user.add_dynamic_attribute(:gunslinger, "boolean") # a column is already written on the "dynamic_attributes" table, with a null value.
111
107
  @user.add_dynamic_attribute(:middle_name, "string") # a column is already written on the "dynamic_attributes" table, with a null value.
112
- @user.gunslinger = true # saves into memory
108
+ @user.write_dynamic_attribute :gunslinger, true # saves into memory
113
109
  @user.middle_name = "Unknown" # saves into memory
114
110
  @user.save # the respective dynamic attribute columns are written in the dynamic_attributes table
115
111
 
@@ -155,24 +151,24 @@ Here are the different types of dynamic attributes you can save:
155
151
 
156
152
  If you assign a value to a dynamic attribute that isn't the original type, it is ignored.
157
153
 
158
- pre. @user.gunslinger = true
154
+ pre. @user.write_dynamic_attribute :gunslinger, true
159
155
  @user.save
160
- @user.gunslinger # true
161
- @user.gunslinger = "hey there"
156
+ @user.read_dynamic_attribute(:gunslinger) # true
157
+ @user.write_dynamic_attribute :gunslinger, "hey there"
162
158
  @user.save
163
- @user.gunslinger # true
159
+ @user.read_dynamic_attribute(:gunslinger) # true
164
160
 
165
161
  h2. Removing a dynamic attribute
166
162
 
167
163
  pre. @user.remove_dynamic_attribute(:gunslinger)
168
- @user.gunslinger # NoMethodError
164
+ @user.read_dynamic_attribute(:gunslinger) # NoMethodError
169
165
  @user.dynamic_columns # will not include :gunslinger => {...}
170
166
 
171
167
  h2. Ordering
172
168
 
173
169
  You can call
174
170
 
175
- pre. Product.order_dynamic_attribute("price", "float") # returns all users with their dynamic attribute "name" in ascending order
171
+ pre. Product.order_by_dynamic_attribute("price", "float") # returns all users with their dynamic attribute "name" in ascending order
176
172
 
177
173
  Why pass the "float" in the order method? Because what if 2 different user records both have the dynamic attribute "price", but for one it's a float, and for the other it's an integer? How would you know which to order things by?
178
174
 
@@ -184,11 +180,24 @@ pre. Product.where_dynamic_attribute(:price => 200.0, :rating => 5)
184
180
 
185
181
  As of now it accepts a hash only. If you want to scope to normal attributes, use the normal @where@ method.
186
182
 
183
+ h2. Shortcuts
184
+
185
+ Pretty much all methods that have dynamic_attribute can be shorter:
186
+
187
+ |_. Long name |_. Short name |
188
+ | write_dynamic_attribute | write_datt |
189
+ | read_dynamic_attribute | read_datt |
190
+ | update_dynamic_attribute | update_datt |
191
+ | update_dynamic_attributes | update_datts |
192
+ | find_by_dynamic_attribute_ | find_by_datt_ |
193
+ | order_by_dynamic_attribute | order_by_datt |
194
+ | where_dynamic_attribute | where_datt |
195
+
187
196
  h2. Contributing to dynamic_attributes_right
188
197
 
189
198
  There are definitely things that don't work, and could be done better. For example, it would be nice to:
190
199
 
191
- # Do away with the special scopes, such as @where_dynamic_attribute@ and @order_dynamic_attribute@. I've tried to override ActiveRecord to make the normal @where@ and @order@ methods to see if the attributes being passed were dynamic, and do the changes necessary to the resulting SQL, but my head "started to hurt":http://stackoverflow.com/q/5590191/61018.
200
+ # Do away with the special scopes, such as @where_dynamic_attribute@ and @order_by_dynamic_attribute@. I've tried to override ActiveRecord to make the normal @where@ and @order@ methods to see if the attributes being passed were dynamic, and do the changes necessary to the resulting SQL, but my head "started to hurt":http://stackoverflow.com/q/5590191/61018.
192
201
  # Have smarter caching, so that finds with dynamic attributes aren't very expensive.
193
202
  # Have configurable "dynamic_attributes" table
194
203
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.8
1
+ 0.0.9
data/datts_right.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{datts_right}
8
- s.version = "0.0.8"
8
+ s.version = "0.0.9"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ramon Tayag"]
12
- s.date = %q{2011-04-12}
12
+ s.date = %q{2011-04-17}
13
13
  s.description = %q{Creates a separate table that saves all your dynamic attributes.}
14
14
  s.email = %q{ramon@tayag.net}
15
15
  s.extra_rdoc_files = [
@@ -170,6 +170,12 @@ Gem::Specification.new do |s|
170
170
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
171
171
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
172
172
  s.add_development_dependency(%q<rcov>, [">= 0"])
173
+ s.add_development_dependency(%q<autotest>, [">= 0"])
174
+ s.add_development_dependency(%q<sqlite3>, [">= 0"])
175
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
176
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
177
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
178
+ s.add_development_dependency(%q<rcov>, [">= 0"])
173
179
  else
174
180
  s.add_dependency(%q<datts_right>, [">= 0"])
175
181
  s.add_dependency(%q<rails>, [">= 3.0.0"])
@@ -288,6 +294,12 @@ Gem::Specification.new do |s|
288
294
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
289
295
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
290
296
  s.add_dependency(%q<rcov>, [">= 0"])
297
+ s.add_dependency(%q<autotest>, [">= 0"])
298
+ s.add_dependency(%q<sqlite3>, [">= 0"])
299
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
300
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
301
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
302
+ s.add_dependency(%q<rcov>, [">= 0"])
291
303
  end
292
304
  else
293
305
  s.add_dependency(%q<datts_right>, [">= 0"])
@@ -407,6 +419,12 @@ Gem::Specification.new do |s|
407
419
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
408
420
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
409
421
  s.add_dependency(%q<rcov>, [">= 0"])
422
+ s.add_dependency(%q<autotest>, [">= 0"])
423
+ s.add_dependency(%q<sqlite3>, [">= 0"])
424
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
425
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
426
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
427
+ s.add_dependency(%q<rcov>, [">= 0"])
410
428
  end
411
429
  end
412
430
 
data/lib/datts_right.rb CHANGED
@@ -13,6 +13,8 @@ module DattsRight
13
13
 
14
14
  has_many :dynamic_attributes, :as => :attributable, :dependent => :destroy
15
15
 
16
+ after_find :cache_dynamic_attributes
17
+
16
18
  # Carry out delayed actions before save
17
19
  before_save :build_dynamic_attributes
18
20
 
@@ -13,12 +13,14 @@ class DynamicAttribute < ActiveRecord::Base
13
13
  # only allow object_type changes if this is NOT a new record
14
14
  # and it's text to string or vice versa
15
15
  interchangeable_types = %w(text string)
16
- #puts "It's currently a #{self.object_type}, and we wanna make it a #{object_type}"
16
+ #puts "#{attr_key} is currently a #{self.object_type}, and we wanna make it a #{object_type}"
17
17
  if !new_record? && interchangeable_types.include?(self.object_type) && interchangeable_types.include?(object_type) && self.object_type != object_type
18
- #puts "It's not new, and we're setting it to #{object_type}"
18
+ #puts "#{attr_key} is not new, and we're setting object_type to #{object_type}"
19
19
  self.object_type = object_type
20
+ send "#{self.class.attr_column(v)}=", v
21
+ elsif self.object_type == object_type # has to be the same kind of object
22
+ send "#{self.object_type}_value=", v
20
23
  end
21
- send("#{self.class.attr_column(v)}=", v)
22
24
  end
23
25
 
24
26
  def self.attr_type?(v)
@@ -1,100 +1,34 @@
1
1
  module DattsRight
2
2
  module InstanceMethods
3
- def add_dynamic_attribute(name, klass)
4
- key = name.to_s
5
- unless attributes.keys.include?(key)
6
- dynamic_attribute = dynamic_attributes.find_by_attr_key(key.underscore)
7
- unless dynamic_attribute
8
- dynamic_attribute = dynamic_attributes.create :name => key, :attr_key => key.underscore, :object_type => klass
9
- dynamic_columns(true)
10
- end
11
- #puts "Just added #{key} to #{self.class.name}##{id}, and here are the dynamic_attributes: #{dynamic_columns.inspect}"
12
- dynamic_attribute
13
- else
14
- false
3
+ def add_dynamic_attribute(name, object_type, value=nil)
4
+ key = name.to_s.underscore
5
+ return false if self.class.columns_hash[key] # if key already exists as a normal attribute
6
+ unless dynamic_attribute?(key)
7
+ new_dynamic_attribute = dynamic_attributes.new :name => name, :attr_key => key, :object_type => object_type, "#{object_type}_value".to_sym => value
8
+ @dynamic_attributes_cache[key.to_sym] = new_dynamic_attribute
9
+ return new_dynamic_attribute
15
10
  end
11
+ return false
16
12
  end
17
13
 
18
14
  def remove_dynamic_attribute(name)
19
- name = name.to_s
20
- dynamic_attribute = dynamic_attributes.find_by_attr_key(name)
15
+ dynamic_attribute = dynamic_attributes.find_by_attr_key(name.to_s)
21
16
  if dynamic_attribute
17
+ @dynamic_attributes_cache.delete(name.to_sym)
22
18
  dynamic_attribute.destroy
23
- dynamic_columns(true)
24
19
  end
25
20
  end
26
21
 
27
- # Works like ActiveRecord's attributes except it returns dynamic attributes only
28
- #def dynamic_attributes(reload=false)
29
- #puts "dynamic_attributes called with reload? #{reload}"
30
- #@dynamic_attributes ||= {}
31
- #return @dynamic_attributes if !reload
32
- ##puts "Reloading dynamic_attributes"
33
- #dynamic_attributes.each do |dynamic_attribute|
34
- ##puts "Adding this to @dynamic_attributes: #{dynamic_attribute.attr_key} => #{dynamic_attribute.value}"
35
- #@dynamic_attributes.merge({dynamic_attribute.attr_key => dynamic_attribute.value})
36
- #end
37
- ##puts "Here are teh dynamic_attributes: #{dynamic_attributes.inspect}, and this is what we're returning: #{@dynamic_attributes}"
38
- #@dynamic_attributes.symbolize_keys!
39
- #end
40
-
41
- # Because we cannot determine the difference between the inexistence
42
- # between key value pair point to nil (eg :hi => nil) and
43
- # the key not existing, we need to have a different method to return
44
- # information about the record in this format:
45
- # {:price => {:object_type => "integer", :value => 200}}
46
- def dynamic_columns(reload=false)
47
- @dynamic_columns ||= {}
48
- @dynamic_columns if !reload
49
- #puts "Building the dynamic_columns cache, and we'll look through #{dynamic_attributes.count} dynamic_attributes"
50
- @dynamic_columns={}
51
- dynamic_attributes.reload
52
- dynamic_attributes.each do |dynamic_attribute|
53
- #puts "Going through dynamic_attribute##{dynamic_attribute.id}"
54
- dynamic_column = {
55
- dynamic_attribute.attr_key.to_sym => {
56
- :object_type => dynamic_attribute.object_type,
57
- :value => dynamic_attribute.value
58
- }
59
- }
60
- #puts "Added #{dynamic_column.inspect} to the dynamic columns"
61
- @dynamic_columns.merge!(dynamic_column)
62
- end
63
- #puts "in dynamic_columns, returning: #{@dynamic_columns.inspect}"
64
- @dynamic_columns
22
+ # Give users access to the cache
23
+ def dynamic_attribute_details(key)
24
+ @dynamic_attributes_cache[key]
65
25
  end
66
26
 
67
27
  # Determines if the given attribute is a dynamic attribute.
68
28
  def dynamic_attribute?(attr)
69
- #puts "in dynamic_attribute?(:#{attr}). dynamic_attributes: #{dynamic_attributes.inspect}. Datt: #{Datt.all.inspect}"
70
- #dynamic_columns.include?(attr.to_s)
71
- !dynamic_columns[attr.to_sym].nil?
72
- #return dynamic_attributes.include?(attr.to_sym) unless dynamic_attributes.empty?
73
- #return false if self.class.column_names.include?(attr.to_s)
74
- #false
29
+ !@dynamic_attributes_cache[attr.to_sym].nil?
75
30
  end
76
31
 
77
- # This overrides the attributes= defined in ActiveRecord::Base
78
- # The only difference is that this doesn't check to see if the
79
- # model responds_to the method before sending it
80
- #def attributes=(new_attributes, guard_protected_attributes = true)
81
- #return unless new_attributes.is_a?(Hash)
82
- #attributes = new_attributes.stringify_keys
83
-
84
- #multi_parameter_attributes = []
85
- #attributes = sanitize_for_mass_assignment(attributes) if guard_protected_attributes
86
-
87
- #attributes.each do |k, v|
88
- #if k.include?("(")
89
- #multi_parameter_attributes << [ k, v ]
90
- #else
91
- #send("#{k}=", v)
92
- #end
93
- #end
94
-
95
- #assign_multiparameter_attributes(multi_parameter_attributes)
96
- #end
97
-
98
32
  def update_dynamic_attributes(attributes)
99
33
  # The following transaction covers any possible database side-effects of the
100
34
  # attributes assignment. For example, setting the IDs of a child collection.
@@ -115,43 +49,26 @@ module DattsRight
115
49
  end
116
50
  end
117
51
 
118
- # Overrides AR::Base#read_attribute
52
+ # Like AR::Base#read_attribute
119
53
  def read_dynamic_attribute(attr_name)
120
54
  attr_name = attr_name.to_s
121
55
  if dynamic_attribute?(attr_name)
122
- #puts "trying to read dynamic_attribute #{attr_name}"
123
- # If value is in the @save_dynamic_attr cache, and it's not blank
124
- if !@save_dynamic_attr.blank? and @save_dynamic_attr[attr_name]
125
- #puts "dynamic_attribute #{attr_name} IS in cache, so let's return its value"
126
- # Then we return the value
127
- return @save_dynamic_attr[attr_name]
128
- else # The value is not there, or it's blank
129
- #puts "dynamic_attribute #{attr_name} is NOT in cache, so let's load it from the dynamic_attribute table"
130
- #attrs = read_attribute_without_dynamic_attributes(dynamic_attributes_options[:column_name].to_s)
131
- #puts "Here are ALL the dynamic_attributes: #{Datt.all.inspect} and my id is: #{id}"
132
- #puts "Here are my the dynamic_attributes: #{dynamic_attributes.inspect} and my id is: #{id}. and the first dynamic_attribute's value is #{dynamic_attributes.first.value}"
133
- dynamic_attribute = dynamic_attributes.find_by_attr_key(attr_name)
134
- #puts "This is the dat I find: #{dynamic_attribute.inspect}"
135
- return dynamic_attribute.try(:value)
136
- #attrs = attrs.nil? ? nil : YAML.load(attrs).symbolize_keys! unless attrs.is_a? Hash
137
- #return nil if attrs.blank?
138
- #return attrs[attr_name.to_sym]
139
- end
56
+ #puts "Reading #{attr_name}. The whole cache: #{@dynamic_attributes_cache.inspect}"
57
+ @dynamic_attributes_cache[attr_name.to_sym].value
140
58
  end
141
-
142
- super(attr_name)
143
59
  end
144
60
 
145
- # Overrides AR::Base#write_attribute
61
+ # Like AR::Base#write_attribute
146
62
  def write_dynamic_attribute(attr_name, value)
147
63
  #puts "attempting to write: #{attr_name} = #{value}"
148
64
  if dynamic_attribute?(attr_name)
149
65
  #puts "#{attr_name} is a dynamic_attribute"
150
66
  attr_name = attr_name.to_s
151
-
152
- @save_dynamic_attr ||= {} # create the cache if needed
153
- return @save_dynamic_attr[attr_name] = value
154
- return nil
67
+ #puts "Writing @dynamic_attributes_cache[:#{attr_name}].value = #{value}"
68
+ dynamic_attribute = @dynamic_attributes_cache[attr_name.to_sym]
69
+ dynamic_attribute.value = value
70
+ #puts "In write_dynamic_attribute. Full cache: #{@dynamic_attributes_cache.inspect}"
71
+ return dynamic_attribute.value
155
72
  end
156
73
  end
157
74
 
@@ -161,52 +78,33 @@ module DattsRight
161
78
  # like normal attributes in the fact that the database is not touched
162
79
  # until save is called.
163
80
  def build_dynamic_attributes
164
- return if @save_dynamic_attr.nil?
165
- # This originally saves things into the "dynamic_attributes" column.
166
- #write_attribute_without_dynamic_attributes "dynamic_attributes", @save_dynamic_attr
167
- # We save things into the dynamic_attributes table
168
- @save_dynamic_attr.each do |k, v|
169
- k = k.to_s
170
- dynamic_attribute = dynamic_attributes.find_by_attr_key(k)
171
- #puts "to create or to update #{k}?"
172
- if dynamic_attribute
173
- dynamic_attribute.update_attribute(:value, v)
174
- #puts "updated: #{dynamic_attribute.inspect}"
81
+ @dynamic_attributes_cache ||= {}
82
+ @dynamic_attributes_cache.each do |k, v|
83
+ v.save
84
+ #dynamic_attribute = dynamic_attributes.find_by_attr_key(k.to_s)
85
+ #value_column = "#{v[:object_type]}_value".to_sym
86
+ #if dynamic_attribute
87
+ #dynamic_attribute.update_attributes value_column => v[:value], :object_type => v[:object_type]
175
88
  #else
176
- #dynamic_attribute = dynamic_attributes.create! :name => k, :attr_key => k, :value => v
177
- #puts "created: #{dynamic_attribute.inspect} among these dynamic_attributes: #{dynamic_attributes.inspect}"
178
- end
89
+ ##@dynamic_attributes_cache[k] = dynamic_attributes.create! :name => k, :attr_key => k, value_column => v[:value], :object_type => v[:object_type]
90
+ #@dynamic_attributes_cache[k].save
91
+ #end
179
92
  end
180
- @save_dynamic_attr = {}
181
- true
182
93
  end
183
94
 
184
- # Implements dynamic-attributes as if real getter/setter methods
185
- # were defined.
186
- #def method_missing(method_id, *args, &block)
187
- #puts "in DattsRight::InstanceMethods#method_missing with method_id #{method_id}"
188
- #begin
189
- #super method_id, *args, &block
190
- #rescue NoMethodError => e
191
- #puts "AR doesn't have #{method_id} so DattsRight will take care of it instead"
192
- #attr_name = method_id.to_s.sub(/\=$/, '')
193
- ##puts "Now we check to see if price is a dynamic attribute. dynamic_columns: #{dynamic_columns}. is #{attr_name} in those dynamic_columns? #{dynamic_attribute?(attr_name)}"
194
- #if dynamic_attribute?(attr_name)
195
- ##puts "== And #{method_id} is a dynamic method"
196
- #if method_id.to_s =~ /\=$/
197
- #return write_attribute(attr_name, args[0])
198
- #else
199
- #return read_attribute(attr_name)
200
- #end
201
- #end
202
- #raise e
203
- #end
204
- #end
95
+ def cache_dynamic_attributes
96
+ @dynamic_attributes_cache = {}
97
+ dynamic_attributes.each do |dynamic_attribute|
98
+ @dynamic_attributes_cache[dynamic_attribute.attr_key.to_sym] = dynamic_attribute
99
+ end
100
+ @dynamic_attributes_cache
101
+ end
205
102
 
206
103
  alias :add_datt :add_dynamic_attribute
207
104
  alias :remove_datt :remove_dynamic_attribute
208
105
  alias :read_datt :read_dynamic_attribute
209
106
  alias :write_datt :write_dynamic_attribute
107
+ alias :datt_details :dynamic_attribute_details
210
108
  alias :update_dynamic_attribute :write_dynamic_attribute
211
109
  end
212
110
  end
@@ -11,15 +11,17 @@ describe DattsRight do
11
11
  Page.instance_method(:add_dynamic_attribute).should == Page.instance_method(:add_datt)
12
12
  end
13
13
 
14
- it "should add a dynamic attribute with nil value" do
14
+ it "should add a dynamic attribute" do
15
15
  @page.add_dynamic_attribute(:rocks, "string")
16
- @page.dynamic_columns[:rocks][:value].should be_nil
16
+ @page.dynamic_attribute_details(:rocks).value.should be_nil
17
+ @page.add_dynamic_attribute(:rock, "string", "123")
18
+ @page.dynamic_attribute_details(:rock).value.should == "123"
17
19
  end
18
20
 
19
21
  it "should ignore when trying to add same attribute" do
20
22
  @page.add_dynamic_attribute(:rocks, "string")
21
23
  @page.add_dynamic_attribute(:rocks, "integer")
22
- @page.dynamic_columns[:rocks][:object_type].should == "string"
24
+ @page.dynamic_attribute_details(:rocks).object_type.should == "string"
23
25
  end
24
26
 
25
27
  it "should return false if the method that is being added already exists" do
@@ -28,9 +30,14 @@ describe DattsRight do
28
30
 
29
31
  it "should not make any changes to the original attribute" do
30
32
  @page.update_attribute(:name, "juno")
31
- @page.add_dynamic_attribute(:name, "text").should be_false
33
+ @page.add_dynamic_attribute(:name, "text")
32
34
  @page.name.should == "juno"
33
35
  end
36
+
37
+ it "should still work after reloading" do
38
+ @page.add_dynamic_attribute(:rocks, "string")
39
+ @page = Page.last
40
+ end
34
41
  end
35
42
 
36
43
  describe ".remove_dynamic_attribute(attr_key)" do
@@ -396,4 +403,15 @@ describe DattsRight do
396
403
  Page.where_dynamic_attribute(:bogus_field => "none").should be_empty
397
404
  end
398
405
  end
406
+
407
+ describe ".dynamic_attribute_details(key)" do
408
+ it "should be aliased by datt_details" do
409
+ Page.instance_method(:dynamic_attribute_details).should == Page.instance_method(:datt_details)
410
+ end
411
+
412
+ it "should allow access to the dynamic_attribute" do
413
+ @page.add_dynamic_attribute(:price, "integer")
414
+ @page.dynamic_attribute_details(:price).class.should == DynamicAttribute
415
+ end
416
+ end
399
417
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datts_right
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 8
10
- version: 0.0.8
9
+ - 9
10
+ version: 0.0.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ramon Tayag
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-12 00:00:00 +08:00
18
+ date: 2011-04-17 00:00:00 +08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -1774,6 +1774,96 @@ dependencies:
1774
1774
  name: rcov
1775
1775
  version_requirements: *id117
1776
1776
  prerelease: false
1777
+ - !ruby/object:Gem::Dependency
1778
+ type: :development
1779
+ requirement: &id118 !ruby/object:Gem::Requirement
1780
+ none: false
1781
+ requirements:
1782
+ - - ">="
1783
+ - !ruby/object:Gem::Version
1784
+ hash: 3
1785
+ segments:
1786
+ - 0
1787
+ version: "0"
1788
+ name: autotest
1789
+ version_requirements: *id118
1790
+ prerelease: false
1791
+ - !ruby/object:Gem::Dependency
1792
+ type: :development
1793
+ requirement: &id119 !ruby/object:Gem::Requirement
1794
+ none: false
1795
+ requirements:
1796
+ - - ">="
1797
+ - !ruby/object:Gem::Version
1798
+ hash: 3
1799
+ segments:
1800
+ - 0
1801
+ version: "0"
1802
+ name: sqlite3
1803
+ version_requirements: *id119
1804
+ prerelease: false
1805
+ - !ruby/object:Gem::Dependency
1806
+ type: :development
1807
+ requirement: &id120 !ruby/object:Gem::Requirement
1808
+ none: false
1809
+ requirements:
1810
+ - - ~>
1811
+ - !ruby/object:Gem::Version
1812
+ hash: 3
1813
+ segments:
1814
+ - 2
1815
+ - 3
1816
+ - 0
1817
+ version: 2.3.0
1818
+ name: rspec
1819
+ version_requirements: *id120
1820
+ prerelease: false
1821
+ - !ruby/object:Gem::Dependency
1822
+ type: :development
1823
+ requirement: &id121 !ruby/object:Gem::Requirement
1824
+ none: false
1825
+ requirements:
1826
+ - - ~>
1827
+ - !ruby/object:Gem::Version
1828
+ hash: 23
1829
+ segments:
1830
+ - 1
1831
+ - 0
1832
+ - 0
1833
+ version: 1.0.0
1834
+ name: bundler
1835
+ version_requirements: *id121
1836
+ prerelease: false
1837
+ - !ruby/object:Gem::Dependency
1838
+ type: :development
1839
+ requirement: &id122 !ruby/object:Gem::Requirement
1840
+ none: false
1841
+ requirements:
1842
+ - - ~>
1843
+ - !ruby/object:Gem::Version
1844
+ hash: 7
1845
+ segments:
1846
+ - 1
1847
+ - 5
1848
+ - 2
1849
+ version: 1.5.2
1850
+ name: jeweler
1851
+ version_requirements: *id122
1852
+ prerelease: false
1853
+ - !ruby/object:Gem::Dependency
1854
+ type: :development
1855
+ requirement: &id123 !ruby/object:Gem::Requirement
1856
+ none: false
1857
+ requirements:
1858
+ - - ">="
1859
+ - !ruby/object:Gem::Version
1860
+ hash: 3
1861
+ segments:
1862
+ - 0
1863
+ version: "0"
1864
+ name: rcov
1865
+ version_requirements: *id123
1866
+ prerelease: false
1777
1867
  description: Creates a separate table that saves all your dynamic attributes.
1778
1868
  email: ramon@tayag.net
1779
1869
  executables: []