toast 0.9.5 → 1.0.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.
@@ -1,175 +0,0 @@
1
- module Toast
2
-
3
- class ResourceNotFound < Exception; end
4
- class MethodNotAllowed < Exception; end
5
- class PayloadInvalid < Exception; end
6
- class Conflict < Exception; end
7
- class PayloadFormatError < Exception; end
8
- class UnsupportedMediaType < Exception; end
9
- class RequestedVersionNotDefined < Exception; end
10
- class ResourceNotAcceptable < Exception; end
11
- class BadRequest < Exception; end
12
-
13
- # Represents a resource. There are following resource types as sub classes:
14
- # Record, Collection, Association, Single
15
- class Resource
16
-
17
- attr_accessor :prefered_media_type, :base_uri, :payload_content_type
18
-
19
- def initialize
20
- raise 'ToastResource#new: use #build to create an instance'
21
- end
22
-
23
- def self.build params, request
24
- resource_name = params[:resource]
25
- id = params[:id]
26
- subresource_name = params[:subresource]
27
- format = params[:format]
28
-
29
- begin
30
-
31
- # determine model
32
- model = get_class_by_resource_name resource_name
33
-
34
- # determine config for representation
35
- # config_in: cosumed representation
36
- # config_out: produced representation
37
- config_out = model.toast_config request.accept_media_types.prefered
38
- config_in = model.toast_config request.media_type
39
-
40
- # ... or in case of an association request
41
- config_assoc_src = model.toast_config request.headers["Assoc-source-type"] # ?
42
-
43
- # base URI for returned object
44
- base_uri = request.base_url + request.script_name +
45
- (config_out.namespace ? "/" + config_out.namespace : "")
46
-
47
- # decide which sub resource type
48
- rsc = if id.nil? and config_out.singles.include?(subresource_name)
49
- Toast::Single.new(model, subresource_name, params.clone, config_in, config_out)
50
- elsif id.nil?
51
- Toast::Collection.new(model, subresource_name, params.clone, config_in, config_out)
52
- elsif subresource_name.nil?
53
- Toast::Record.new(model, id, format, params.clone, config_in, config_out)
54
- elsif (config_assoc_src && config_assoc_src.exposed_associations.include?(subresource_name))
55
-
56
- # determine associated model
57
- assoc_model =
58
- model.reflect_on_all_associations.detect{|a| a.name.to_s == subresource_name}.klass
59
-
60
- # determine config for representation of assoc. model
61
- assoc_config_out = assoc_model.toast_config request.accept_media_types.prefered
62
- assoc_config_in = assoc_model.toast_config request.media_type
63
-
64
- # change base URI to associated record
65
- base_uri = request.base_url + request.script_name +
66
- (assoc_config_out.namespace ? "/" + assoc_config_out.namespace : "")
67
-
68
-
69
- Toast::Association.new(model, id, subresource_name, params.clone, format, config_assoc_src,
70
- assoc_model, assoc_config_in, assoc_config_out)
71
-
72
- else
73
- raise ResourceNotFound
74
- end
75
-
76
- # set base to be prepended to URIs
77
- rsc.base_uri = base_uri
78
-
79
-
80
-
81
- rsc
82
- rescue NameError
83
- raise ResourceNotFound
84
- end
85
- end
86
-
87
- def self.get_class_by_resource_name name
88
- begin
89
- model = name.singularize.classify.constantize # raises NameError
90
-
91
- unless ((model.superclass == ActiveRecord::Base) and model.is_resourceful_model?)
92
- raise ResourceNotFound
93
- end
94
-
95
- model
96
-
97
- rescue NameError
98
- raise ResourceNotFound
99
- end
100
- end
101
-
102
- def apply method, payload, payload_media_type, link_path_info
103
- case method
104
- when "PUT","POST"
105
- if link_path_info
106
- self.link link_path_info
107
- else
108
- self.send(method.downcase, payload, payload_media_type)
109
- end
110
- when "DELETE"
111
- if link_path_info
112
- self.unlink link_path_info
113
- else
114
- self.delete
115
- end
116
- when "GET"
117
- self.get
118
- else
119
- raise MethodNotAllowed
120
- end
121
- end
122
-
123
- private
124
- def uri_fields record, in_collection=false
125
- out = {}
126
-
127
- exposed_assoc =
128
- in_collection ? record.class.toast_config.in_collection.exposed_associations :
129
- record.class.toast_config.exposed_associations
130
-
131
- exposed_assoc.each do |assoc|
132
- out[assoc] = "#{self.base_uri}#{record.uri_path}/#{assoc}"
133
- end
134
-
135
- out["self"] = self.base_uri + record.uri_path
136
-
137
- out
138
- end
139
-
140
-
141
- def paginate_query config, relation_name, relation, params
142
-
143
- if pagination = config.paginations[relation_name] and params[:page] =~ /\d+/
144
-
145
- raise Toast::BadRequest.new("Page 0 not defined. Paging starts with 1") if params[:page].to_i == 0
146
-
147
- ps = pagination[:page_size].to_i
148
- total = relation.count
149
-
150
- page = params[:page].to_i
151
- total_pages = (total/ps) + (total%ps == 0 ? 0 : 1)
152
-
153
- pagination_info = {:total => total}
154
-
155
- if total_pages > 0
156
-
157
- if page > total_pages
158
- pagination_info[:prev] = total_pages
159
- else
160
- pagination_info[:prev] = page - 1 unless page == 1
161
- pagination_info[:next] = page + 1 if page < total_pages
162
- end
163
-
164
- pagination_info[:last] = total_pages
165
- else
166
- pagination_info[:last] = 1
167
- end
168
-
169
- [relation.limit(ps).offset((page-1) * ps), pagination_info]
170
- else
171
- [relation, nil]
172
- end
173
- end
174
- end
175
- end
data/lib/toast/single.rb DELETED
@@ -1,89 +0,0 @@
1
- module Toast
2
-
3
- # A Single resource is queried without an ID, by custom class methods
4
- # or scopes of the model or ActiveRecord single finders like:
5
- # first, last
6
-
7
- # The single resource name must be a class method of the model and
8
- # must return nil or an instance.
9
-
10
- # GET is the only allowed verb. To make changes the URI with ID has
11
- # to be used.
12
- class Single < Resource
13
-
14
- attr_reader :model
15
-
16
- def initialize model, subresource_name, params, config_in, config_out
17
- @config_in = config_in
18
- @config_out = config_out
19
-
20
- unless @config_out.singles.include? subresource_name
21
- raise ResourceNotFound
22
- end
23
-
24
- @model = model
25
- @params = params
26
- @format = params[:format]
27
-
28
- unless @model.respond_to?(subresource_name)
29
- raise "Toast Error: Cannot find class method '#{@model}.#{subresource_name}', which is configured in 'acts_as_resource > singles'."
30
- end
31
-
32
- @record = if @config_out.pass_params_to.include?(subresource_name)
33
- if @model.method(subresource_name).arity != 1
34
- raise "Toast Error: Class method '#{@model}.#{subresource_name}' must accept one parameter, as configured by 'acts_as_resource > pass_params_to'."
35
- end
36
- @model.send(subresource_name, @params)
37
- else
38
- if(@model.method(subresource_name).arity < -1 or
39
- @model.method(subresource_name).arity > 0)
40
- raise "Toast Error: Class method '#{@model}.#{subresource_name}' must be callable w/o parameters"
41
- end
42
- @model.send(subresource_name)
43
- end
44
-
45
- raise ResourceNotFound if @record.nil?
46
- end
47
-
48
- def get
49
- case @format
50
- when "html"
51
- {
52
- :template => "resources/#{model.to_s.underscore}",
53
- :locals => { model.to_s.pluralize.underscore.to_sym => @record }
54
- }
55
- when "json"
56
- {
57
- :json => @record.represent( @config_out.exposed_attributes,
58
- @config_out.exposed_associations,
59
- @base_uri,
60
- @config_out.media_type),
61
- :status => :ok
62
- }
63
- else
64
- raise ResourceNotFound
65
- end
66
- end
67
-
68
-
69
- def put
70
- raise MethodNotAllowed
71
- end
72
-
73
- def post payload
74
- raise MethodNotAllowed
75
- end
76
-
77
- def delete
78
- raise MethodNotAllowed
79
- end
80
-
81
- def link l
82
- raise MethodNotAllowed
83
- end
84
-
85
- def unlink l
86
- raise MethodNotAllowed
87
- end
88
- end
89
- end