nakajima-sinatras-hat 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,17 +5,13 @@ class Array
5
5
 
6
6
  def move_to_front(*entries)
7
7
  entries.each do |entry|
8
- if deleted = delete(entry)
9
- unshift(deleted)
10
- end
8
+ unshift(entry) if delete(entry)
11
9
  end
12
10
  end
13
11
 
14
12
  def move_to_back(*entries)
15
13
  entries.each do |entry|
16
- if deleted = delete(entry)
17
- push(deleted)
18
- end
14
+ push(entry) if delete(entry)
19
15
  end
20
16
  end
21
17
  end
@@ -0,0 +1,15 @@
1
+ module Sinatra
2
+ module Hat
3
+ class Action
4
+ attr_reader :maker, :handler
5
+
6
+ def initialize(maker, name, handler)
7
+ @maker, @handler = maker, handler
8
+ end
9
+
10
+ def handle(event)
11
+ handler[event.params]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -9,52 +9,44 @@ module Sinatra
9
9
  end
10
10
 
11
11
  def index!
12
- map :index, resource_path('/') do |params|
12
+ map :index, '/' do |params|
13
13
  call(:finder, params)
14
14
  end
15
15
  end
16
16
 
17
17
  def new!
18
- map :new, resource_path('/new') do |params|
18
+ map :new, '/new' do |params|
19
19
  proxy(params).new
20
20
  end
21
21
  end
22
22
 
23
23
  def edit!
24
- map :edit, resource_path('/:id/edit') do |params|
24
+ map :edit, '/:id/edit' do |params|
25
25
  call(:record, params)
26
26
  end
27
27
  end
28
28
 
29
29
  def show!
30
- map :show, resource_path('/:id') do |params|
30
+ map :show, '/:id' do |params|
31
31
  call(:record, params)
32
32
  end
33
33
  end
34
34
 
35
35
  def create!
36
- map :create, resource_path('/'), :verb => :post do |params|
37
- result = proxy(params).new
38
- result.attributes = parse_for_attributes(params)
39
- result.save
40
- result
36
+ map :create, '/', :verb => :post do |params|
37
+ create[proxy(params), parse_for_attributes(params)]
41
38
  end
42
39
  end
43
40
 
44
41
  def update!
45
- map :update, resource_path('/:id'), :verb => :put do |params|
46
- result = call(:record, params)
47
- result.attributes = parse_for_attributes(params)
48
- result.save
49
- result
42
+ map :update, '/:id', :verb => :put do |params|
43
+ update[call(:record, params), parse_for_attributes(params)]
50
44
  end
51
45
  end
52
46
 
53
47
  def destroy!
54
- map :destroy, resource_path('/:id'), :verb => :delete do |params|
55
- result = call(:record, params)
56
- result.destroy
57
- :ok
48
+ map :destroy, '/:id', :verb => :delete do |params|
49
+ destroy[call(:record, params), parse_for_attributes(params)]
58
50
  end
59
51
  end
60
52
 
@@ -62,12 +54,12 @@ module Sinatra
62
54
 
63
55
  def parse_for_attributes(params, name=model.name.downcase)
64
56
  if handler = accepts[params[:format].try(:to_sym)]
65
- handler.call params[name]
57
+ params.merge(name => handler.call(params[name]))
66
58
  else
67
59
  params.nest!
68
60
  params[name] ||= { }
69
61
  params[name][parent.model_id] = params[parent.model_id] if parent
70
- params[name]
62
+ params
71
63
  end
72
64
  end
73
65
  end
@@ -3,7 +3,7 @@ module Sinatra
3
3
  class Maker
4
4
  attr_accessor :parent
5
5
  attr_reader :model, :context, :options
6
-
6
+
7
7
  include Actions, Responses
8
8
 
9
9
  def initialize(model)
@@ -102,12 +102,76 @@ module Sinatra
102
102
  end
103
103
  end
104
104
 
105
+ def create(&block)
106
+ if block_given?
107
+ @create = block
108
+ else
109
+ @create ||= proc do |model, params|
110
+ result = model.new
111
+ result.attributes = params[model_name]
112
+ result.save ? result : nil
113
+ end
114
+ end
115
+ end
116
+
117
+ def update(&block)
118
+ if block_given?
119
+ @update = block
120
+ else
121
+ @update ||= proc do |record, params|
122
+ record.attributes = params[model_name]
123
+ record.save ? record : false
124
+ end
125
+ end
126
+ end
127
+
128
+ def destroy(&block)
129
+ if block_given?
130
+ @destroy = block
131
+ else
132
+ @destroy ||= proc do |record, params|
133
+ record.destroy
134
+ :destroyed
135
+ end
136
+ end
137
+ end
138
+
105
139
  def map(name, path, opts={}, &block)
106
140
  opts[:verb] ||= :get
107
141
  klass = self
142
+ actions[name] = Action.new(self, name, block)
143
+
144
+ context.send(opts[:verb], resource_path(path)) do
145
+ begin
146
+ klass.templated(self, name, opts)
147
+ rescue Errno::ENOENT => e
148
+ klass.rescue_template_error(e)
149
+ end
150
+ end
151
+
152
+ context.send(opts[:verb], "#{resource_path(path)}.:format") do
153
+ begin
154
+ klass.serialized(self, name, opts)
155
+ rescue UnsupportedFormat => e
156
+ klass.rescue_format_error(e)
157
+ end
158
+ end
159
+ end
108
160
 
109
- context.send(opts[:verb], path) { klass.templated(self, name, opts, &block) }
110
- context.send(opts[:verb], "#{path}.:format") { klass.serialized(self, name, opts, &block) }
161
+ def rescue_format_error(e)
162
+ throw :halt, [
163
+ 406, [
164
+ "The `#{e.format}` format is not supported.\n",
165
+ "Valid Formats: #{accepts.keys.join(', ')}\n",
166
+ ].join("\n")
167
+ ]
168
+ end
169
+
170
+ # TODO Create a real template for this error.
171
+ def rescue_template_error(e)
172
+ msg = "<pre>There was a problem with your view template:\n\n "
173
+ msg << e.message
174
+ msg << "\n</pre>"
111
175
  end
112
176
 
113
177
  def call(method, params)
@@ -123,14 +187,19 @@ module Sinatra
123
187
  end
124
188
 
125
189
  def model_id
126
- "#{model.name.downcase}_id".to_sym
190
+ "#{model_name}_id".to_sym
191
+ end
192
+
193
+ def model_name
194
+ model.name.downcase
127
195
  end
128
196
 
129
197
  def options
130
198
  @options ||= {
131
199
  :only => [:new, :edit, :show, :create, :update, :destroy, :index],
132
200
  :prefix => Extlib::Inflection.tableize(model.name),
133
- :protect => [],
201
+ :actions => { },
202
+ :protect => [ ],
134
203
  :formats => { },
135
204
  :renderer => :erb,
136
205
  :children => [],
@@ -1,40 +1,49 @@
1
1
  module Sinatra
2
2
  module Hat
3
+ # TODO: Move these to Action class?
3
4
  module Responses
4
- def templated(event, name, opts={}, &block)
5
+ class UnsupportedFormat < StandardError
6
+ attr_reader :format
7
+
8
+ def initialize(format)
9
+ @format = format
10
+ end
11
+ end
12
+
13
+ def templated(event, name, opts={})
5
14
  event.protect!(:realm => credentials[:realm], &authenticator) if protecting?(name)
6
15
 
7
16
  root = File.join(Sinatra.application.options.views, prefix)
8
- result = block.call(event.params)
17
+ result = actions[name].handle(event)
9
18
  event.instance_variable_set ivar_name(result), result
10
19
  return opts[:verb] == :get ?
11
20
  event.render(renderer, name, :views_directory => root) :
12
21
  event.redirect(redirection_path(result))
13
22
  end
14
23
 
15
- def serialized(event, name, opts={}, &block)
24
+ def serialized(event, name, opts={})
16
25
  format = event.params[:format].to_sym
17
26
 
18
27
  event.protect!(:realm => credentials[:realm], &authenticator) if protecting?(name)
19
28
 
20
29
  if accepts[format] or opts[:verb].eql?(:get)
21
- event.content_type format rescue nil
22
- object = block.call(event.params)
23
- handle = formats[format.to_sym]
24
- result = handle ? handle.call(object) : object.try("to_#{format}")
30
+ event.content_type(format) rescue nil
31
+ object = actions[name].handle(event)
32
+ result = serializer_for(format).call(object)
25
33
  return result unless result.nil?
26
34
  end
27
35
 
28
- throw :halt, [
29
- 406, [
30
- "The `#{format}` format is not supported.\n",
31
- "Valid Formats: #{accepts.keys.join(', ')}\n",
32
- ].join("\n")
33
- ]
36
+ raise UnsupportedFormat.new(format)
34
37
  end
35
38
 
36
39
  private
37
40
 
41
+ def serializer_for(format)
42
+ formats[format.to_sym] ||= proc do |object|
43
+ object.try("to_#{format}")
44
+ end
45
+ end
46
+
38
47
  def protecting?(name)
39
48
  protect.include?(:all) or protect.include?(name)
40
49
  end
data/lib/sinatras-hat.rb CHANGED
@@ -8,6 +8,7 @@ require 'dm-serializer'
8
8
  require 'array'
9
9
  require 'hash'
10
10
  require 'object'
11
+ require 'action'
11
12
  require 'actions'
12
13
  require 'responses'
13
14
  require 'maker'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nakajima-sinatras-hat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Nakajima
@@ -54,6 +54,7 @@ files:
54
54
  - lib/core_ext/object.rb
55
55
  - lib/sinatras-hat
56
56
  - lib/sinatras-hat/maker.rb
57
+ - lib/sinatras-hat/action.rb
57
58
  - lib/sinatras-hat/actions.rb
58
59
  - lib/sinatras-hat/auth.rb
59
60
  - lib/sinatras-hat/responses.rb