datts_right 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- datts_right (0.0.4)
4
+ datts_right (0.0.5)
5
5
  datts_right
6
6
  rails (>= 3.0.0)
7
7
 
data/README.textile CHANGED
@@ -12,23 +12,41 @@ h2. Why make this?
12
12
  # The "available":http://codaset.com/joelmoss/dynamic-attributes "plugins":https://github.com/moiristo/dynamic_attributes out there that did something like this stuffed the dynamic attributes in a column in the model that had dynamic attributes. Because of this, you:
13
13
  ** Could not order things by dynamic columns straight with SQL
14
14
  ** Could not (as far as I know) chain scopes, like so: @MyModel.where(:name_which_is_a_real_attribute => "Joe").where_datt(:phone_which_is_dynamic => "23218793")@
15
- ** Could not find by dynamic attribute straight with SQL, like so: @MyModel.find_by_phone_which_is_dynamic("2398291308")@
15
+ ** Could not find by dynamic attribute straight with SQL, like so: @MyModel.find_by_datt_phone_which_is_dynamic("2398291308")@
16
16
  ** Had to add migrations to each model that you wanted to have dynamic attributes
17
17
 
18
18
  h2. Installation
19
19
 
20
20
  Create a migration:
21
21
 
22
- pre. create_table :datts do |t|
23
- t.string :name, :null => false
24
- t.string :attr_key, :null => false
25
- t.string :object_type, :null => false
26
- t.string :attributable_type, :null => false
27
- t.integer :attributable_id, :null => false
28
- %w(integer string boolean text float).each do |type|
29
- t.send(type, "#{type}_value".to_sym)
22
+ <pre>
23
+ class CreateDatts < ActiveRecord::Migration
24
+ def self.up
25
+ create_table(:datts) do |t|
26
+ t.string :name, :null => false
27
+ t.string :attr_key, :null => false
28
+ t.string :object_type, :null => false
29
+ t.string :attributable_type, :null => false
30
+ t.integer :attributable_id, :null => false
31
+ %w(integer string boolean text float).each do |type|
32
+ t.send(type, "#{type}_value".to_sym)
33
+ end
34
+ end
35
+
36
+ add_index "datts", ["attributable_id"], :name => "index_datts_on_attributable_id"
37
+ add_index "datts", ["attributable_type"], :name => "index_datts_on_attributable_type"
38
+ add_index "datts", ["attr_key"], :name => "index_datts_on_attr_key"
39
+ end
40
+
41
+ def self.down
42
+ remove_index "datts", :name => "index_datts_on_attr_key"
43
+ remove_index "datts", :name => "index_datts_on_attributable_type"
44
+ remove_index "datts", :name => "index_datts_on_attributable_id"
45
+
46
+ drop_table(:datts)
30
47
  end
31
48
  end
49
+ </pre>
32
50
 
33
51
  * *name* is not important at the moment, but I intend to make better use of it in the future.
34
52
  * *attr_key* the name of the dynamic attribute
@@ -76,6 +94,15 @@ h3. dynamic_attribute?(:some_attribute)
76
94
 
77
95
  Returns true or false
78
96
 
97
+ h3. Dynamic find
98
+
99
+ pre. User.find_by_datt_age(240) # returns the first user with that age
100
+
101
+ You can also use:
102
+
103
+ pre. find_all_by_datt
104
+ find_last_by_datt
105
+
79
106
  h2. Stuff that make things faster
80
107
 
81
108
  The dynamic attributes are only actually saved when save is called on the record that has them.
@@ -155,7 +182,7 @@ You can do:
155
182
 
156
183
  pre. Product.where_datt(:price => 200.0, :rating => 5)
157
184
 
158
- As of now it accepts a hash only. If you want to search normal attributes, use the normal @where@ method.
185
+ As of now it accepts a hash only. If you want to scope to normal attributes, use the normal @where@ method.
159
186
 
160
187
  h2. Contributing to datts_right
161
188
 
@@ -177,8 +204,7 @@ If you want to contribute:
177
204
  * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
178
205
  * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
179
206
 
180
- == Copyright
207
+ h2. Copyright
181
208
 
182
209
  Copyright (c) 2011 Ramon Tayag. See LICENSE.txt for
183
210
  further details.
184
-
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.0.6
data/datts_right.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{datts_right}
8
- s.version = "0.0.5"
8
+ s.version = "0.0.6"
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"]
@@ -148,6 +148,12 @@ Gem::Specification.new do |s|
148
148
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
149
149
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
150
150
  s.add_development_dependency(%q<rcov>, [">= 0"])
151
+ s.add_development_dependency(%q<autotest>, [">= 0"])
152
+ s.add_development_dependency(%q<sqlite3>, [">= 0"])
153
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
154
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
155
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
156
+ s.add_development_dependency(%q<rcov>, [">= 0"])
151
157
  else
152
158
  s.add_dependency(%q<datts_right>, [">= 0"])
153
159
  s.add_dependency(%q<rails>, [">= 3.0.0"])
@@ -242,6 +248,12 @@ Gem::Specification.new do |s|
242
248
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
243
249
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
244
250
  s.add_dependency(%q<rcov>, [">= 0"])
251
+ s.add_dependency(%q<autotest>, [">= 0"])
252
+ s.add_dependency(%q<sqlite3>, [">= 0"])
253
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
254
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
255
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
256
+ s.add_dependency(%q<rcov>, [">= 0"])
245
257
  end
246
258
  else
247
259
  s.add_dependency(%q<datts_right>, [">= 0"])
@@ -337,6 +349,12 @@ Gem::Specification.new do |s|
337
349
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
338
350
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
339
351
  s.add_dependency(%q<rcov>, [">= 0"])
352
+ s.add_dependency(%q<autotest>, [">= 0"])
353
+ s.add_dependency(%q<sqlite3>, [">= 0"])
354
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
355
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
356
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
357
+ s.add_dependency(%q<rcov>, [">= 0"])
340
358
  end
341
359
  end
342
360
 
data/lib/datts_right.rb CHANGED
@@ -68,11 +68,65 @@ module DattsRight
68
68
 
69
69
  def self.method_missing(method_id, *arguments)
70
70
  # TODO better way to hook this into the rails code, and not define my own
71
- if method_id.to_s =~ /^find_(all_|last_)?by_([_a-zA-Z]\w*)$/
72
- attributes = $2.split("_and_")
73
- #puts "Will find by #{attributes.inspect}"
74
- arg = arguments.first
75
- scope_self.joins(:datts).where("datts.#{Datt.attr_column(arg)} = :value", :value => arg)
71
+ begin # Prioritize ActiveRecord's method_missing
72
+ super(method_id, *arguments)
73
+ rescue NoMethodError => e
74
+ #puts "Method missing: #{method_id}"
75
+ if method_id.to_s =~ /^find_(all_|last_)?by_datt_([_a-z]\w*)$/
76
+ all_or_last = $1
77
+ attributes = $2.split("_and_")
78
+ results = self
79
+ attributes.each_with_index do |attribute, i|
80
+ results = results.where_datt(attribute.to_sym => arguments[i])
81
+ end
82
+
83
+ #puts "this is $1 of the method '#{method_id}': #{all_or_last}."
84
+ case all_or_last
85
+ when "all_"
86
+ results
87
+ when "last_"
88
+ results.last
89
+ when nil
90
+ results.first
91
+ else
92
+ nil
93
+ end
94
+ else
95
+ raise e
96
+ end
97
+
98
+ #if method_id.to_s =~ /^find_(all_|last_)by_datt_([_a-z]\w*)$/
99
+ #all_or_last = $1
100
+ #attributes = $2.split("_and_")
101
+ #results = self
102
+ #attributes.each_with_index do |attribute, i|
103
+ #results = results.where_datt(attribute.to_sym => arguments[i])
104
+ #end
105
+
106
+ #puts "this is $1 of the method '#{method_id}': #{all_or_last}."
107
+ #case all_or_last
108
+ #when "all_"
109
+ #results
110
+ #when "last_"
111
+ #results.last
112
+ #else
113
+ #nil
114
+ #end
115
+ #elsif method_id.to_s =~ /^find_by_datt_([_a-z]\w*)$/
116
+ ##puts "returning a find_by_datt_#{$1}"
117
+ #attributes = $1.split("_and_")
118
+ ##puts "here are the attributes: #{attributes.inspect}"
119
+ #results = self
120
+ #attributes.each_with_index do |attribute, i|
121
+ ##puts "Adding where_datt(:#{attribute} => #{arguments[i]})"
122
+ #results = results.where_datt(attribute.to_sym => arguments[i])
123
+ #end
124
+
125
+ ##puts "Will return the FIRST of #{results.to_sql}"
126
+ #results.first
127
+ #else
128
+ #nil
129
+ #end
76
130
  end
77
131
  end
78
132
 
@@ -48,7 +48,7 @@ describe DattsRight do
48
48
  describe ".dynamic_columns(reload)" do
49
49
  it "should return an array of symbols of the available dynamic columns" do
50
50
  @page.add_dynamic_attribute(:rocks, "string")
51
- @page.is_dynamic_attribute?(:rocks).should be_true
51
+ @page.dynamic_attribute?(:rocks).should be_true
52
52
  end
53
53
  end
54
54
 
@@ -135,11 +135,11 @@ describe DattsRight do
135
135
  @page.farce = "Nothing here my friend"
136
136
  @page.save
137
137
  @page.farce = nil
138
- @page.is_dynamic_attribute?(:farce).should be_true
138
+ @page.dynamic_attribute?(:farce).should be_true
139
139
  end
140
140
 
141
- describe "on dynamic find_by methods" do
142
- it "should work" do
141
+ describe "on dynamic find_by_datt methods" do
142
+ it "should be able to return single records" do
143
143
  @page.add_dynamic_attribute(:price, "integer")
144
144
  @page.price = 400
145
145
  @page.save
@@ -149,8 +149,53 @@ describe DattsRight do
149
149
  @page_2.price = 500
150
150
  @page_2.save
151
151
 
152
- Page.find_by_price(400).should include(@page)
153
- Page.find_by_price(400).should_not include(@page_2)
152
+ Page.find_by_datt_price(400).should == @page
153
+ Page.find_by_datt_price(400).should_not == @page_2
154
+ end
155
+
156
+ it "should be able to return all matching records" do
157
+ @page.add_dynamic_attribute(:price, "integer")
158
+ @page.price = 400
159
+ @page.save
160
+
161
+ @page_2 = Page.create
162
+ @page_2.add_dynamic_attribute(:price, "integer")
163
+ @page_2.price = 500
164
+ @page_2.save
165
+
166
+ @page_3 = Page.create
167
+ @page_3.add_dynamic_attribute(:price, "integer")
168
+ @page_3.price = 400
169
+ @page_3.save
170
+
171
+ @results = Page.find_all_by_datt_price(400)
172
+ @results.should include(@page)
173
+ @results.should_not include(@page_2)
174
+ @results.should include(@page_3)
175
+ end
176
+
177
+ it "should still allow raising of NoMethodError if the original attribute does not exist" do
178
+ lambda { Page.find_by_faker("hi") }.should raise_error(NoMethodError)
179
+ end
180
+
181
+ it "should be able to return the last record" do
182
+ @page.add_dynamic_attribute(:price, "integer")
183
+ @page.price = 400
184
+ @page.save
185
+
186
+ @page_2 = Page.create
187
+ @page_2.add_dynamic_attribute(:price, "integer")
188
+ @page_2.price = 400
189
+ @page_2.save
190
+
191
+ Page.find_last_by_datt_price(400) == @page_2
192
+ end
193
+
194
+ it "should allow normal attributes to work" do
195
+ @page.name = "Roland"
196
+ @page.save
197
+
198
+ Page.find_by_name("Roland").should == @page
154
199
  end
155
200
 
156
201
  it "should allow chaining" do
@@ -164,9 +209,9 @@ describe DattsRight do
164
209
  @page_2.price = 500
165
210
  @page_2.save
166
211
 
167
- @pages = Page.where(:name => "fixed").find_by_price(400)
168
- @pages.should include(@page)
169
- @pages.should_not include(@page_2)
212
+ @pages = Page.where(:name => "fixed").find_by_datt_price(400)
213
+ @pages.should == @page
214
+ @pages.should_not == @page_2
170
215
  end
171
216
  end
172
217
 
@@ -174,19 +219,19 @@ describe DattsRight do
174
219
  @page.add_dynamic_attribute(:price, "integer")
175
220
  @page.price = 400
176
221
  @page.add_dynamic_attribute(:farce, "string")
177
- @page.farce = "hi"
222
+ @page.farce = "hitt"
178
223
  @page.save
179
224
 
180
225
  @page_2 = Page.create
181
226
  @page_2.add_dynamic_attribute(:price, "integer")
182
227
  @page_2.price = 400
183
228
  @page_2.add_dynamic_attribute(:farce, "string")
184
- @page_2.farce = "hitt"
229
+ @page_2.farce = "hi"
185
230
  @page_2.save
186
231
 
187
- @pages = Page.find_by_farce_and_price("hi", 400)
188
- @pages.should include(@page)
189
- @pages.should_not include(@page_2)
232
+ @pages = Page.find_by_datt_price_and_farce(400, "hi")
233
+ @pages.should == @page_2
234
+ @pages.should_not == @page
190
235
  end
191
236
 
192
237
  describe "when the value being assigned is not of the same type (with exceptions)" do
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: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ramon Tayag
@@ -1414,6 +1414,96 @@ dependencies:
1414
1414
  name: rcov
1415
1415
  version_requirements: *id093
1416
1416
  prerelease: false
1417
+ - !ruby/object:Gem::Dependency
1418
+ type: :development
1419
+ requirement: &id094 !ruby/object:Gem::Requirement
1420
+ none: false
1421
+ requirements:
1422
+ - - ">="
1423
+ - !ruby/object:Gem::Version
1424
+ hash: 3
1425
+ segments:
1426
+ - 0
1427
+ version: "0"
1428
+ name: autotest
1429
+ version_requirements: *id094
1430
+ prerelease: false
1431
+ - !ruby/object:Gem::Dependency
1432
+ type: :development
1433
+ requirement: &id095 !ruby/object:Gem::Requirement
1434
+ none: false
1435
+ requirements:
1436
+ - - ">="
1437
+ - !ruby/object:Gem::Version
1438
+ hash: 3
1439
+ segments:
1440
+ - 0
1441
+ version: "0"
1442
+ name: sqlite3
1443
+ version_requirements: *id095
1444
+ prerelease: false
1445
+ - !ruby/object:Gem::Dependency
1446
+ type: :development
1447
+ requirement: &id096 !ruby/object:Gem::Requirement
1448
+ none: false
1449
+ requirements:
1450
+ - - ~>
1451
+ - !ruby/object:Gem::Version
1452
+ hash: 3
1453
+ segments:
1454
+ - 2
1455
+ - 3
1456
+ - 0
1457
+ version: 2.3.0
1458
+ name: rspec
1459
+ version_requirements: *id096
1460
+ prerelease: false
1461
+ - !ruby/object:Gem::Dependency
1462
+ type: :development
1463
+ requirement: &id097 !ruby/object:Gem::Requirement
1464
+ none: false
1465
+ requirements:
1466
+ - - ~>
1467
+ - !ruby/object:Gem::Version
1468
+ hash: 23
1469
+ segments:
1470
+ - 1
1471
+ - 0
1472
+ - 0
1473
+ version: 1.0.0
1474
+ name: bundler
1475
+ version_requirements: *id097
1476
+ prerelease: false
1477
+ - !ruby/object:Gem::Dependency
1478
+ type: :development
1479
+ requirement: &id098 !ruby/object:Gem::Requirement
1480
+ none: false
1481
+ requirements:
1482
+ - - ~>
1483
+ - !ruby/object:Gem::Version
1484
+ hash: 7
1485
+ segments:
1486
+ - 1
1487
+ - 5
1488
+ - 2
1489
+ version: 1.5.2
1490
+ name: jeweler
1491
+ version_requirements: *id098
1492
+ prerelease: false
1493
+ - !ruby/object:Gem::Dependency
1494
+ type: :development
1495
+ requirement: &id099 !ruby/object:Gem::Requirement
1496
+ none: false
1497
+ requirements:
1498
+ - - ">="
1499
+ - !ruby/object:Gem::Version
1500
+ hash: 3
1501
+ segments:
1502
+ - 0
1503
+ version: "0"
1504
+ name: rcov
1505
+ version_requirements: *id099
1506
+ prerelease: false
1417
1507
  description: Creates a separate table that saves all your dynamic attributes.
1418
1508
  email: ramon@tayag.net
1419
1509
  executables: []