autoforme 1.0.3 → 1.1.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +17 -2
- data/lib/autoforme/framework.rb +22 -2
- data/lib/autoforme/model.rb +16 -5
- data/lib/autoforme/models/sequel.rb +5 -5
- data/lib/autoforme/version.rb +1 -1
- data/spec/associations_spec.rb +5 -5
- data/spec/basic_spec.rb +82 -9
- data/spec/mtm_spec.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 728834eb84059f820d99421609b8f274868fa06f
|
4
|
+
data.tar.gz: 497582c00ccd77bcb14f716ae5596d32210ae33e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e71852cb6b1b049123b388d944789f8678b392724d299d776cd9ea43dd5ef3f6230d81135e11d6589a0610feb957e2838a1a3fd83181676f146089ec8832b837
|
7
|
+
data.tar.gz: ed0cecfc641fccdd7e1337421c3fdab68d38f4b1cbddbb470744924ffde7e9d35ab5e0c6b8205df8908bea8630a12ce392b9846fadb9f76166e0149495fe16cd
|
data/CHANGELOG
CHANGED
data/MIT-LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -55,8 +55,8 @@ for Sinatra:
|
|
55
55
|
end
|
56
56
|
|
57
57
|
Let's break down how this works. You setup AutoForme using <tt>AutoForme.for</tt>,
|
58
|
-
which takes 2 arguments, the controller type symbol (currently either :sinatra or :rails),
|
59
|
-
and the controller class (either a Sinatra::Base or ActionController::Base subclass). You
|
58
|
+
which takes 2 arguments, the controller type symbol (currently either :sinatra, :roda, or :rails),
|
59
|
+
and the controller class (either a Sinatra::Base, Roda, or ActionController::Base subclass). You
|
60
60
|
pass <tt>AutoForme.for</tt> a block, which is instance evaled at the framework level. This
|
61
61
|
level sets the defaults.
|
62
62
|
|
@@ -212,6 +212,21 @@ AutoForme's javascript support is contained in the autoforme.js file in the root
|
|
212
212
|
of the distribution. AutoForme's autocompleting support also requires
|
213
213
|
https://github.com/dyve/jquery-autocomplete
|
214
214
|
|
215
|
+
= Reloading Code
|
216
|
+
|
217
|
+
By default, AutoForme stores classes by reference. This can cause issues when using
|
218
|
+
code reloading in development environments. You can call +register_by_name+ to set
|
219
|
+
Autoforme to store classes by name, so that if a class is removed and reloaded (giving
|
220
|
+
a new class reference), it will use the new class instead of the reference to the old
|
221
|
+
class. Example:
|
222
|
+
|
223
|
+
class App < Sinatra::Base
|
224
|
+
AutoForme.for(:sinatra, self) do
|
225
|
+
register_by_name
|
226
|
+
model Artist
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
215
230
|
= TODO
|
216
231
|
|
217
232
|
* capybara-webkit tests for ajax behavior
|
data/lib/autoforme/framework.rb
CHANGED
@@ -116,10 +116,30 @@ module AutoForme
|
|
116
116
|
handle_proc(association_links, model, type, request)
|
117
117
|
end
|
118
118
|
|
119
|
+
# Set whether to register classes by name instead of by reference
|
120
|
+
def register_by_name(register=true)
|
121
|
+
opts[:register_by_name] = register
|
122
|
+
end
|
123
|
+
|
124
|
+
# Whether to register classes by name instead of by reference
|
125
|
+
def register_by_name?
|
126
|
+
opts[:register_by_name]
|
127
|
+
end
|
128
|
+
|
129
|
+
# Look up the Autoforme::Model class to use for the underlying model class instance.
|
130
|
+
def model_class(model_class)
|
131
|
+
if register_by_name?
|
132
|
+
model_class = model_class.name
|
133
|
+
end
|
134
|
+
@model_classes[model_class]
|
135
|
+
end
|
136
|
+
|
119
137
|
# Add a new model to the existing framework.
|
120
138
|
def model(model_class, &block)
|
121
|
-
|
122
|
-
|
139
|
+
if register_by_name?
|
140
|
+
model_class = model_class.name
|
141
|
+
end
|
142
|
+
model = @model_classes[model_class] = Model.for(self, model_type, model_class, &block)
|
123
143
|
@models[model.link] = model
|
124
144
|
end
|
125
145
|
|
data/lib/autoforme/model.rb
CHANGED
@@ -13,6 +13,9 @@ module AutoForme
|
|
13
13
|
# The default supported actions for models.
|
14
14
|
DEFAULT_SUPPORTED_ACTIONS = [:browse, :new, :show, :edit, :delete, :search, :mtm_edit]
|
15
15
|
|
16
|
+
# Regexp for valid constant names, to prevent code execution.
|
17
|
+
VALID_CONSTANT_NAME_REGEXP = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.freeze
|
18
|
+
|
16
19
|
extend OptsAttributes
|
17
20
|
|
18
21
|
# Create a new instance for the given model type and underlying model class
|
@@ -26,9 +29,6 @@ module AutoForme
|
|
26
29
|
# The AutoForme::Framework class tied to the current model
|
27
30
|
attr_reader :framework
|
28
31
|
|
29
|
-
# The underlying model class for the current model
|
30
|
-
attr_reader :model
|
31
|
-
|
32
32
|
# The options for the given model.
|
33
33
|
attr_reader :opts
|
34
34
|
|
@@ -47,6 +47,17 @@ module AutoForme
|
|
47
47
|
@opts = {}
|
48
48
|
end
|
49
49
|
|
50
|
+
# The underlying model class for the current model
|
51
|
+
def model
|
52
|
+
if @model.is_a?(Class)
|
53
|
+
@model
|
54
|
+
elsif m = VALID_CONSTANT_NAME_REGEXP.match(@model)
|
55
|
+
Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
|
56
|
+
else
|
57
|
+
raise Error, "invalid model for AutoForme::Model, not a class or valid constant name: #{@model.inspect}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
50
61
|
# Whether the given type of action is supported for this model.
|
51
62
|
def supported_action?(type, request)
|
52
63
|
v = (handle_proc(supported_actions || framework.supported_actions_for(model, request), request) || DEFAULT_SUPPORTED_ACTIONS).include?(type)
|
@@ -223,7 +234,7 @@ module AutoForme
|
|
223
234
|
|
224
235
|
# The AutoForme::Model instance associated to the given association.
|
225
236
|
def associated_model_class(assoc)
|
226
|
-
framework.
|
237
|
+
framework.model_class(associated_class(assoc))
|
227
238
|
end
|
228
239
|
|
229
240
|
# The column value to display for the given object and column.
|
@@ -283,7 +294,7 @@ module AutoForme
|
|
283
294
|
# Create a new instance of the underlying model, setting
|
284
295
|
# defaults based on the params given.
|
285
296
|
def new(params, request)
|
286
|
-
obj =
|
297
|
+
obj = model.new
|
287
298
|
if params
|
288
299
|
columns_for(:new, request).each do |col|
|
289
300
|
if association?(col)
|
@@ -11,7 +11,7 @@ module AutoForme
|
|
11
11
|
# Make sure the forme plugin is loaded into the model.
|
12
12
|
def initialize(*)
|
13
13
|
super
|
14
|
-
|
14
|
+
model.plugin :forme
|
15
15
|
end
|
16
16
|
|
17
17
|
# The base class for the underlying model, ::Sequel::Model.
|
@@ -21,7 +21,7 @@ module AutoForme
|
|
21
21
|
|
22
22
|
# A completely empty search object, with no defaults.
|
23
23
|
def new_search
|
24
|
-
|
24
|
+
model.call({})
|
25
25
|
end
|
26
26
|
|
27
27
|
# The name of the form param for the given association.
|
@@ -120,7 +120,7 @@ module AutoForme
|
|
120
120
|
# The namespace for form parameter names for this model, needs to match
|
121
121
|
# the ones automatically used by Forme.
|
122
122
|
def params_name
|
123
|
-
|
123
|
+
model.send(:underscore, model.name)
|
124
124
|
end
|
125
125
|
|
126
126
|
# Retrieve underlying model instance with matching primary key
|
@@ -329,7 +329,7 @@ module AutoForme
|
|
329
329
|
private
|
330
330
|
|
331
331
|
def dataset_for(type, request)
|
332
|
-
ds =
|
332
|
+
ds = model.dataset
|
333
333
|
if filter = filter_for
|
334
334
|
ds = filter.call(ds, type, request)
|
335
335
|
end
|
@@ -337,7 +337,7 @@ module AutoForme
|
|
337
337
|
end
|
338
338
|
|
339
339
|
def all_dataset_for(type, request)
|
340
|
-
apply_dataset_options(type, request,
|
340
|
+
apply_dataset_options(type, request, model.dataset)
|
341
341
|
end
|
342
342
|
end
|
343
343
|
end
|
data/lib/autoforme/version.rb
CHANGED
data/spec/associations_spec.rb
CHANGED
@@ -215,7 +215,7 @@ describe AutoForme do
|
|
215
215
|
click_link 'Album'
|
216
216
|
page.all('td').map{|s| s.text}.should == ["Album1b", "A2", "Show", "Edit", "Delete"]
|
217
217
|
|
218
|
-
click_link 'Delete'
|
218
|
+
click_link 'Delete', :match=>:first
|
219
219
|
select 'A2-Album1b'
|
220
220
|
click_button 'Delete'
|
221
221
|
end
|
@@ -293,7 +293,7 @@ describe AutoForme do
|
|
293
293
|
click_link 'Album'
|
294
294
|
page.all('tr td:first-child').map{|s| s.text}.should == %w'Y ZZ X'
|
295
295
|
|
296
|
-
click_link 'Delete'
|
296
|
+
click_link 'Delete', :match=>:first
|
297
297
|
page.all('select option').map{|s| s.text}.should == ['', 'A-Y', 'A-ZZ', 'B-X']
|
298
298
|
select 'B-X'
|
299
299
|
click_button 'Delete'
|
@@ -359,7 +359,7 @@ describe AutoForme do
|
|
359
359
|
click_link 'Album'
|
360
360
|
page.all('tr td:first-child').map{|s| s.text}.should == %w'C D E'
|
361
361
|
|
362
|
-
click_link 'Delete'
|
362
|
+
click_link 'Delete', :match=>:first
|
363
363
|
page.all('select option').map{|s| s.text}.should == ['', 'C', 'D', 'E']
|
364
364
|
select 'C'
|
365
365
|
click_button 'Delete'
|
@@ -410,7 +410,7 @@ describe AutoForme do
|
|
410
410
|
click_link 'Artist'
|
411
411
|
page.current_path.should == '/Artist/browse'
|
412
412
|
|
413
|
-
click_link 'Edit'
|
413
|
+
click_link 'Edit', :match=>:first
|
414
414
|
select 'Artist1'
|
415
415
|
click_button 'Edit'
|
416
416
|
click_link 'Album1'
|
@@ -490,7 +490,7 @@ describe AutoForme do
|
|
490
490
|
click_link 'Artist'
|
491
491
|
page.current_path.should == '/Artist/browse'
|
492
492
|
|
493
|
-
click_link 'Edit'
|
493
|
+
click_link 'Edit', :match=>:first
|
494
494
|
select 'Artist1'
|
495
495
|
click_button 'Edit'
|
496
496
|
click_link 'Show Associations'
|
data/spec/basic_spec.rb
CHANGED
@@ -12,20 +12,20 @@ describe AutoForme do
|
|
12
12
|
it "should have basic functionality working" do
|
13
13
|
app_setup(Artist)
|
14
14
|
visit("/Artist/new")
|
15
|
-
page.
|
15
|
+
page.title.should == 'Artist - New'
|
16
16
|
fill_in 'Name', :with=>'TestArtistNew'
|
17
17
|
click_button 'Create'
|
18
18
|
page.html.should =~ /Created Artist/
|
19
19
|
page.current_path.should == '/Artist/new'
|
20
20
|
|
21
21
|
click_link 'Show'
|
22
|
-
page.
|
22
|
+
page.title.should == 'Artist - Show'
|
23
23
|
select 'TestArtistNew'
|
24
24
|
click_button 'Show'
|
25
25
|
page.html.should =~ /Name.+TestArtistNew/m
|
26
26
|
|
27
27
|
click_link 'Edit'
|
28
|
-
page.
|
28
|
+
page.title.should == 'Artist - Edit'
|
29
29
|
select 'TestArtistNew'
|
30
30
|
click_button 'Edit'
|
31
31
|
fill_in 'Name', :with=>'TestArtistUpdate'
|
@@ -35,7 +35,7 @@ describe AutoForme do
|
|
35
35
|
page.current_path.should =~ %r{/Artist/edit/\d+}
|
36
36
|
|
37
37
|
click_link 'Search'
|
38
|
-
page.
|
38
|
+
page.title.should == 'Artist - Search'
|
39
39
|
fill_in 'Name', :with=>'Upd'
|
40
40
|
click_button 'Search'
|
41
41
|
page.all('th').map{|s| s.text}.should == ['Name', 'Show', 'Edit', 'Delete']
|
@@ -47,12 +47,12 @@ describe AutoForme do
|
|
47
47
|
page.all('td').map{|s| s.text}.should == []
|
48
48
|
|
49
49
|
click_link 'Artist'
|
50
|
-
page.
|
50
|
+
page.title.should == 'Artist - Browse'
|
51
51
|
page.all('td').map{|s| s.text}.should == ["TestArtistUpdate", "Show", "Edit", "Delete"]
|
52
52
|
|
53
53
|
page.all('td').last.find('a').click
|
54
54
|
click_button 'Delete'
|
55
|
-
page.
|
55
|
+
page.title.should == 'Artist - Delete'
|
56
56
|
page.html.should =~ /Deleted Artist/
|
57
57
|
page.current_path.should == '/Artist/delete'
|
58
58
|
|
@@ -274,7 +274,7 @@ describe AutoForme do
|
|
274
274
|
a.should == [:show, :browse]
|
275
275
|
a.clear
|
276
276
|
|
277
|
-
click_link 'Delete'
|
277
|
+
click_link 'Delete', :match=>:first
|
278
278
|
Artist.create(:name=>'A')
|
279
279
|
select 'WENTSITRATSET21'
|
280
280
|
click_button 'Delete'
|
@@ -653,7 +653,7 @@ describe AutoForme do
|
|
653
653
|
click_link 'Artist'
|
654
654
|
page.all('tr td:first-child').map{|s| s.text}.should == %w'2 1'
|
655
655
|
|
656
|
-
click_link 'Delete'
|
656
|
+
click_link 'Delete', :match=>:first
|
657
657
|
page.all('option').map{|s| s.text}.should == ['', '2', '1']
|
658
658
|
select '1'
|
659
659
|
click_button 'Delete'
|
@@ -672,7 +672,7 @@ describe AutoForme do
|
|
672
672
|
it "should display decimals in float format in tables" do
|
673
673
|
app_setup(Artist)
|
674
674
|
visit("/Artist/new")
|
675
|
-
page.
|
675
|
+
page.title.should == 'Artist - New'
|
676
676
|
fill_in 'Num', :with=>'1.01'
|
677
677
|
click_button 'Create'
|
678
678
|
click_link 'Artist'
|
@@ -682,3 +682,76 @@ describe AutoForme do
|
|
682
682
|
page.all('tr td:first-child').map{|s| s.text}.should == %w'1.01'
|
683
683
|
end
|
684
684
|
end
|
685
|
+
|
686
|
+
describe AutoForme do
|
687
|
+
before(:all) do
|
688
|
+
db_setup(:artists=>[[:name, :string]])
|
689
|
+
model_setup(:Artist=>[:artists])
|
690
|
+
end
|
691
|
+
after(:all) do
|
692
|
+
Object.send(:remove_const, :Artist)
|
693
|
+
end
|
694
|
+
|
695
|
+
it "should have basic functionality working when reloading code" do
|
696
|
+
app_setup do
|
697
|
+
register_by_name
|
698
|
+
model Artist
|
699
|
+
end
|
700
|
+
artist_class = Artist
|
701
|
+
Object.send(:remove_const, :Artist)
|
702
|
+
::Artist = Class.new(artist_class) do
|
703
|
+
def name
|
704
|
+
"-#{super}-"
|
705
|
+
end
|
706
|
+
def forme_name
|
707
|
+
"[#{name}]"
|
708
|
+
end
|
709
|
+
end
|
710
|
+
visit("/Artist/new")
|
711
|
+
page.title.should == 'Artist - New'
|
712
|
+
fill_in 'Name', :with=>'TestArtistNew'
|
713
|
+
click_button 'Create'
|
714
|
+
page.html.should =~ /Created Artist/
|
715
|
+
page.current_path.should == '/Artist/new'
|
716
|
+
|
717
|
+
click_link 'Show'
|
718
|
+
page.title.should == 'Artist - Show'
|
719
|
+
select '[-TestArtistNew-]'
|
720
|
+
click_button 'Show'
|
721
|
+
page.html.should =~ /Name.+-TestArtistNew-/m
|
722
|
+
|
723
|
+
click_link 'Edit'
|
724
|
+
page.title.should == 'Artist - Edit'
|
725
|
+
select '[-TestArtistNew-]'
|
726
|
+
click_button 'Edit'
|
727
|
+
fill_in 'Name', :with=>'TestArtistUpdate'
|
728
|
+
click_button 'Update'
|
729
|
+
page.html.should =~ /Updated Artist/
|
730
|
+
page.html.should =~ /Name.+-TestArtistUpdate-/m
|
731
|
+
page.current_path.should =~ %r{/Artist/edit/\d+}
|
732
|
+
|
733
|
+
click_link 'Search'
|
734
|
+
page.title.should == 'Artist - Search'
|
735
|
+
fill_in 'Name', :with=>'Upd'
|
736
|
+
click_button 'Search'
|
737
|
+
page.all('th').map{|s| s.text}.should == ['Name', 'Show', 'Edit', 'Delete']
|
738
|
+
page.all('td').map{|s| s.text}.should == ["-TestArtistUpdate-", "Show", "Edit", "Delete"]
|
739
|
+
|
740
|
+
click_link 'Search'
|
741
|
+
fill_in 'Name', :with=>'Foo'
|
742
|
+
click_button 'Search'
|
743
|
+
page.all('td').map{|s| s.text}.should == []
|
744
|
+
|
745
|
+
click_link 'Artist'
|
746
|
+
page.title.should == 'Artist - Browse'
|
747
|
+
page.all('td').map{|s| s.text}.should == ["-TestArtistUpdate-", "Show", "Edit", "Delete"]
|
748
|
+
|
749
|
+
page.all('td').last.find('a').click
|
750
|
+
click_button 'Delete'
|
751
|
+
page.html.should =~ /Deleted Artist/
|
752
|
+
page.current_path.should == '/Artist/delete'
|
753
|
+
|
754
|
+
click_link 'Artist'
|
755
|
+
page.all('td').map{|s| s.text}.should == []
|
756
|
+
end
|
757
|
+
end
|
data/spec/mtm_spec.rb
CHANGED
@@ -36,7 +36,7 @@ describe AutoForme do
|
|
36
36
|
Album.create(:name=>'Album3')
|
37
37
|
|
38
38
|
visit("/Artist/mtm_edit")
|
39
|
-
page.
|
39
|
+
page.title.should == 'Artist - Many To Many Edit'
|
40
40
|
select("Artist1")
|
41
41
|
click_button "Edit"
|
42
42
|
|
@@ -123,7 +123,7 @@ describe AutoForme do
|
|
123
123
|
click_button 'Add'
|
124
124
|
Artist.first.refresh.albums.map{|x| x.name}.sort.should == %w'Album1 Album2'
|
125
125
|
|
126
|
-
click_button 'Remove'
|
126
|
+
click_button 'Remove', :match=>:first
|
127
127
|
Artist.first.refresh.albums.map{|x| x.name}.should == %w'Album2'
|
128
128
|
|
129
129
|
select 'Album3'
|
@@ -158,7 +158,7 @@ describe AutoForme do
|
|
158
158
|
click_button 'Add'
|
159
159
|
Artist.first.refresh.albums.map{|x| x.name}.sort.should == %w'Album1 Album2'
|
160
160
|
|
161
|
-
click_button 'Remove'
|
161
|
+
click_button 'Remove', :match=>:first
|
162
162
|
Artist.first.refresh.albums.map{|x| x.name}.should == %w'Album2'
|
163
163
|
|
164
164
|
fill_in 'Albums', :with=>a3.id.to_s
|
@@ -351,7 +351,7 @@ describe AutoForme do
|
|
351
351
|
Album.create(:name=>'Album3')
|
352
352
|
|
353
353
|
visit("/Artist/mtm_edit")
|
354
|
-
page.
|
354
|
+
page.title.should == 'Artist - Many To Many Edit'
|
355
355
|
select("Artist1")
|
356
356
|
click_button "Edit"
|
357
357
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autoforme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: forme
|