datts_right 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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: []