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 +1 -1
- data/README.textile +38 -12
- data/VERSION +1 -1
- data/datts_right.gemspec +19 -1
- data/lib/datts_right.rb +59 -5
- data/spec/datts_right_spec.rb +59 -14
- metadata +93 -3
data/Gemfile.lock
CHANGED
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.
|
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
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
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
|
-
|
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.
|
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.
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
|
data/spec/datts_right_spec.rb
CHANGED
@@ -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.
|
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.
|
138
|
+
@page.dynamic_attribute?(:farce).should be_true
|
139
139
|
end
|
140
140
|
|
141
|
-
describe "on dynamic
|
142
|
-
it "should
|
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.
|
153
|
-
Page.
|
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").
|
168
|
-
@pages.should
|
169
|
-
@pages.should_not
|
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 = "
|
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 = "
|
229
|
+
@page_2.farce = "hi"
|
185
230
|
@page_2.save
|
186
231
|
|
187
|
-
@pages = Page.
|
188
|
-
@pages.should
|
189
|
-
@pages.should_not
|
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:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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: []
|