rack-backend-api 0.2.3 → 0.3.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.
- data/README.md +4 -0
- data/example/basic_admin.rb +2 -1
- data/lib/backend_api.rb +6 -1
- data/lib/sequel_rack_backend_api_adapter.rb +8 -1
- data/rack-backend-api.gemspec +1 -1
- data/test/spec_backend_api.rb +20 -0
- data/test/spec_sequel_adapter.rb +19 -0
- metadata +4 -4
data/README.md
CHANGED
@@ -256,14 +256,17 @@ Here are the methods to implement, most of them are just aliases for having a si
|
|
256
256
|
- `Model::backend_post( hash-of-values )` Generally equivalent to Model::new, it creates a new entry with provided values and without validating or saving
|
257
257
|
- `Model#backend_delete` Instance method that destroys the entry
|
258
258
|
- `Model#backend_put( hash-of-values )` Generally equivalent to Model::update, it updates an existing entry with provided values and without validating or saving
|
259
|
+
- `Model#backend_values` returns a Hash with the values of the entry
|
259
260
|
|
260
261
|
Others are slightly more sophisticated:
|
261
262
|
|
262
263
|
- `Model#backend_save?` Returns true if the entry is validated and saved. It generally triggers the error messages for the form as well.
|
263
264
|
- `Model#default_backend_columns` This the list of columns in the forms when the list of fields is not provided via `fields` option
|
265
|
+
- `Model#cloning_backend_columns` Default columns used when cloning (allows to get rid of fields like images that you may not wish to clone).
|
264
266
|
- `Model#backend_form( action_url, columns=nil, options={} )` It is only the wrapping of the form without the actual fields. Try to implement it like the Sequel one.
|
265
267
|
- `Model#backend_fields( columns )` These are the actual fields. There is a default behaviour that basically puts a `textarea` for everything. That works in most cases but this is meant to be overridden for a better solution. We recommend [Crushyform](https://rubygems.org/gems/sequel-crushyform) for Sequel because we did it so we know it plays well with BackendAPI, and also because you don't have anything more to do. BackendAPI knows you have [Crushyform](https://rubygems.org/gems/sequel-crushyform) and use it to create the fields.
|
266
268
|
- `Model#backend_delete_form( action_url, options={})` Basically sugar for Model#backend_form but with an empty array for columns, and these options `{:submit_text=>'X', :method=>'DELETE'}` predefined which you can override. We've seen before that it is for creating DELETE forms.
|
269
|
+
- `Model#backend_clone_form( action_url, options={})` Like delete form, but for cloning an entry.
|
267
270
|
- `Model#backend_show` What is sent when PUT or POST is successful and there is no `_destination`. Default is `'OK'`
|
268
271
|
- `Model::sort( array-of-ids )` It is used to do a bulk update of the position field, hence: re-order
|
269
272
|
|
@@ -295,6 +298,7 @@ CHANGE LOG
|
|
295
298
|
0.2.1 Have a title in forms + Only use `_method` if not POST
|
296
299
|
0.2.2 Backend form should accept a block for populating the fields
|
297
300
|
0.2.3 Send a 404 if the entry does not exist
|
301
|
+
0.3.0 Implement cloning functionality
|
298
302
|
|
299
303
|
COPYRIGHT
|
300
304
|
=========
|
data/example/basic_admin.rb
CHANGED
@@ -22,7 +22,8 @@ BASIC_ADMIN = proc{
|
|
22
22
|
api_inst_path = "%s/%s" % [api_model_path,m.id]
|
23
23
|
link = "<a href='%s?_destination=%s&_submit_text=UPDATE'>%s</a>\n" % [api_inst_path,escaped_path,m.to_label]
|
24
24
|
delete_form = m.backend_delete_form(api_inst_path, {:destination=>path})
|
25
|
-
|
25
|
+
clone_form = m.backend_clone_form(api_model_path, {:destination=>path})
|
26
|
+
link+clone_form+delete_form
|
26
27
|
end.join
|
27
28
|
[200,{'Content-Type'=>'text/html'},[title,create_link,list]]
|
28
29
|
}
|
data/lib/backend_api.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class BackendAPI
|
2
|
-
VERSION = [0,
|
2
|
+
VERSION = [0,3,0]
|
3
3
|
WRAP = <<-EOT
|
4
4
|
<!doctype html>
|
5
5
|
<html>
|
@@ -83,6 +83,11 @@ class BackendAPI
|
|
83
83
|
if !@model_name.nil? && ::Object.const_defined?(@model_class_name)
|
84
84
|
@model_class = Kernel.const_get(@model_class_name)
|
85
85
|
@model_instance = @model_class.backend_get(@id.to_i) unless @id.nil?
|
86
|
+
@clone_instance = @model_class.backend_get(@req['clone_id'].to_i) unless @req['clone_id'].nil?
|
87
|
+
unless @clone_instance.nil?
|
88
|
+
@req['fields'] ||= @clone_instance.cloning_backend_columns.map{|k|k.to_s}
|
89
|
+
@req['model'] = @clone_instance.backend_values.select{|k,v| @req['fields'].include?(k.to_s)}
|
90
|
+
end
|
86
91
|
@req['model'] ||= {}
|
87
92
|
send_404 if @model_instance.nil?&&!@id.nil?
|
88
93
|
else
|
@@ -18,6 +18,7 @@ module ::Sequel::Plugins::RackBackendApiAdapter
|
|
18
18
|
end
|
19
19
|
alias backend_delete destroy
|
20
20
|
alias backend_put set
|
21
|
+
alias backend_values values
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
@@ -47,7 +48,12 @@ module ::Sequel::Plugins::RackBackendApiAdapter
|
|
47
48
|
o
|
48
49
|
end
|
49
50
|
|
50
|
-
def backend_delete_form(url, opts={}); backend_form(url, [], {:submit_text=>'X', :method=>'DELETE'}.update(opts)); end
|
51
|
+
def backend_delete_form(url, opts={}); backend_form(url, [], {:submit_text=>'X', :method=>'DELETE'}.update(opts)){}; end
|
52
|
+
def backend_clone_form(url, opts={})
|
53
|
+
backend_form(url, [], {:submit_text=>'CLONE', :method=>'POST'}.update(opts)) do |out|
|
54
|
+
out << "<input type='hidden' name='clone_id' value='#{self.id}' />\n"
|
55
|
+
end
|
56
|
+
end
|
51
57
|
|
52
58
|
def backend_form_title
|
53
59
|
n = self.respond_to?(:to_label) ? self.to_label : self.backend_to_label
|
@@ -73,6 +79,7 @@ module ::Sequel::Plugins::RackBackendApiAdapter
|
|
73
79
|
|
74
80
|
# Can be overridden
|
75
81
|
def default_backend_columns; columns - [:id]; end
|
82
|
+
def cloning_backend_columns; default_backend_columns; end
|
76
83
|
def backend_show; 'OK'; end
|
77
84
|
|
78
85
|
end
|
data/rack-backend-api.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rack-backend-api'
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.3.0"
|
4
4
|
s.platform = Gem::Platform::RUBY
|
5
5
|
s.summary = "A Rack middleware that provides a simple API for your Admin section"
|
6
6
|
s.description = "The purpose of this Rack Middleware is to provide an API that interfaces with database actions in order to build a CMS."
|
data/test/spec_backend_api.rb
CHANGED
@@ -154,6 +154,26 @@ describe 'API Post' do
|
|
154
154
|
res.body.should==('<!-- '+compared.backend_form('/haiku',['title'], {:no_wrap=>'true'})+' -->')
|
155
155
|
res.body.should.match(/name='_no_wrap'.*value='true'/)
|
156
156
|
end
|
157
|
+
|
158
|
+
should 'be able to handle cloning with fields provided' do
|
159
|
+
res = req_lint(BackendAPI.new).post('/haiku', :params => {'clone_id' => '1', 'fields' => ['body']})
|
160
|
+
res.status.should==201
|
161
|
+
cloned = Haiku[1]
|
162
|
+
haiku = Haiku.order(:id).last
|
163
|
+
haiku.id.should.not==cloned.id
|
164
|
+
haiku.title.should==nil
|
165
|
+
haiku.body.should==cloned.body
|
166
|
+
end
|
167
|
+
|
168
|
+
should 'be able to handle cloning using cloning_backend_columns' do
|
169
|
+
res = req_lint(BackendAPI.new).post('/haiku', :params => {'clone_id' => '1'})
|
170
|
+
res.status.should==201
|
171
|
+
cloned = Haiku[1]
|
172
|
+
haiku = Haiku.order(:id).last
|
173
|
+
haiku.id.should.not==cloned.id
|
174
|
+
haiku.title.should==cloned.title
|
175
|
+
haiku.body.should==cloned.body
|
176
|
+
end
|
157
177
|
end
|
158
178
|
|
159
179
|
describe 'API Get' do
|
data/test/spec_sequel_adapter.rb
CHANGED
@@ -16,6 +16,10 @@ describe 'Sequel Adapter' do
|
|
16
16
|
Haiku.new.default_backend_columns.should==(Haiku.columns - [:id])
|
17
17
|
end
|
18
18
|
|
19
|
+
should 'Define Model#cloning_backend_columns' do
|
20
|
+
Haiku.new.cloning_backend_columns.should==(Haiku.columns - [:id])
|
21
|
+
end
|
22
|
+
|
19
23
|
should 'Make forms for the correct action' do
|
20
24
|
Haiku.new.backend_form('/url').should.match(/action='\/url'/)
|
21
25
|
end
|
@@ -82,6 +86,14 @@ describe 'Sequel Adapter' do
|
|
82
86
|
form.scan(/input/).size.should==4
|
83
87
|
end
|
84
88
|
|
89
|
+
should 'Have a backend_clone_form method - pure HTTP way of cloning records with HTTP POST method' do
|
90
|
+
form = Haiku.first.backend_clone_form('/url')
|
91
|
+
form.should.match(/name='_method' value='POST'/)
|
92
|
+
form.should.match(/<input type='submit' name='save' value='CLONE' \/>/)
|
93
|
+
form.should.match(/name='clone_id' value='#{Haiku.first.id}'/)
|
94
|
+
form.scan(/input/).size.should==4
|
95
|
+
end
|
96
|
+
|
85
97
|
should "Be able to sort entries with a list of IDs" do
|
86
98
|
TopFive.sort([2,3,1,5,4])
|
87
99
|
TopFive.order(:position).map(:flavour).should==['Vanilla','Chocolate','Strawberry','Apricot','Coconut']
|
@@ -110,6 +122,13 @@ describe 'Sequel Adapter' do
|
|
110
122
|
Author[1].backend_form('/url').should.match(/#{Regexp.escape(Author[1].backend_form_title)}/)
|
111
123
|
end
|
112
124
|
|
125
|
+
should 'Not include a title on delete and clone forms' do
|
126
|
+
form = Haiku.first.backend_delete_form('/url')
|
127
|
+
form.should.not.match(/<h2>/)
|
128
|
+
form = Haiku.first.backend_clone_form('/url')
|
129
|
+
form.should.not.match(/<h2>/)
|
130
|
+
end
|
131
|
+
|
113
132
|
should 'Yield the given block to populate the form fields' do
|
114
133
|
Author[1].backend_form('/url'){|out| out << '<!-- YIELDED -->'}.should.match(/<!-- YIELDED -->/)
|
115
134
|
Author[1].backend_form('/url', [:name]){|out|}.should.not.match(/#{Regexp.escape Author[1].crushyfield(:name)}/)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-backend-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 2
|
9
8
|
- 3
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mickael Riga
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-25 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|