toast 0.5.2 → 0.6.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/app/controller/toast_controller.rb +1 -1
- data/config/routes.rb +19 -11
- data/lib/toast/active_record_extensions.rb +34 -27
- data/lib/toast/association.rb +29 -19
- data/lib/toast/collection.rb +23 -16
- data/lib/toast/config_dsl.rb +17 -4
- data/lib/toast/engine.rb +1 -0
- data/lib/toast/record.rb +22 -14
- data/lib/toast/resource.rb +49 -17
- data/lib/toast/single.rb +11 -7
- metadata +17 -4
@@ -6,7 +6,7 @@ class ToastController < ApplicationController
|
|
6
6
|
|
7
7
|
@resource = Toast::Resource.build( params, request )
|
8
8
|
|
9
|
-
render @resource.apply(request.method, request.body.read)
|
9
|
+
render @resource.apply(request.method, request.body.read, request.content_type)
|
10
10
|
|
11
11
|
rescue Toast::ResourceNotFound => e
|
12
12
|
return head(:not_found)
|
data/config/routes.rb
CHANGED
@@ -5,17 +5,25 @@ Rails.application.routes.draw do
|
|
5
5
|
|
6
6
|
resource_name = model.to_s.pluralize.underscore
|
7
7
|
|
8
|
-
|
9
|
-
:constraints => { :id => /\d+/ },
|
10
|
-
:resource => resource_name,
|
11
|
-
:as => resource_name,
|
12
|
-
:defaults => { :format => 'json' })
|
13
|
-
|
14
|
-
match("#{model.toast_config.namespace}/#{resource_name}/:subresource" => 'toast#catch_all',
|
15
|
-
:resource => resource_name,
|
16
|
-
:defaults => { :format => 'json' })
|
17
|
-
end
|
8
|
+
namespaces = []
|
18
9
|
|
19
|
-
|
10
|
+
# routes must be defined for all defined namespaces of a model
|
11
|
+
model.toast_configs.each do |tc|
|
12
|
+
# once per namespace
|
13
|
+
next if namespaces.include? tc.namespace
|
14
|
+
|
15
|
+
namespaces << tc.namespace
|
16
|
+
|
17
|
+
match("#{tc.namespace}/#{resource_name}(/:id(/:subresource))" => 'toast#catch_all',
|
18
|
+
:constraints => { :id => /\d+/ },
|
19
|
+
:resource => resource_name,
|
20
|
+
:as => resource_name,
|
21
|
+
:defaults => { :format => 'json' })
|
20
22
|
|
23
|
+
match("#{tc.namespace}/#{resource_name}/:subresource" => 'toast#catch_all',
|
24
|
+
:resource => resource_name,
|
25
|
+
:defaults => { :format => 'json' })
|
26
|
+
end
|
27
|
+
end
|
21
28
|
|
29
|
+
end
|
@@ -4,57 +4,64 @@ require 'toast/config_dsl'
|
|
4
4
|
module Toast
|
5
5
|
module ActiveRecordExtensions
|
6
6
|
|
7
|
-
# Configuration DSL
|
8
|
-
def
|
9
|
-
|
10
|
-
|
7
|
+
# Configuration DSL
|
8
|
+
def acts_as_resource &block
|
9
|
+
|
10
|
+
@toast_configs ||= Array.new
|
11
|
+
|
12
|
+
@toast_configs << Toast::ConfigDSL::Base.new(self)
|
13
|
+
|
14
|
+
Blockenspiel.invoke( block, @toast_configs.last)
|
11
15
|
|
12
16
|
# add class methods
|
13
17
|
self.instance_eval do
|
14
18
|
|
15
|
-
cattr_accessor :uri_base
|
16
|
-
|
17
19
|
def is_resourceful_model?
|
18
20
|
true
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
22
|
-
@
|
23
|
+
def toast_configs
|
24
|
+
@toast_configs
|
25
|
+
end
|
26
|
+
|
27
|
+
# get a config by media type or first one if none matches
|
28
|
+
def toast_config media_type
|
29
|
+
@toast_configs.find do |tc|
|
30
|
+
tc.media_type == media_type || tc.in_collection.media_type == media_type
|
31
|
+
end || @toast_configs.first
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
26
35
|
# add instance methods
|
27
36
|
self.class_eval do
|
28
37
|
# Return the path segment of the URI of this record
|
29
|
-
def
|
38
|
+
def uri_path
|
30
39
|
"/" +
|
31
|
-
(self.class.toast_config.namespace ? self.class.toast_config.namespace+"/" : "") +
|
32
40
|
self.class.to_s.pluralize.underscore + "/" +
|
33
41
|
self.id.to_s
|
34
42
|
end
|
43
|
+
|
44
|
+
# Like ActiveRecord::Base.attributes, but result Hash includes
|
45
|
+
# only attributes from the list _attr_names_ plus the
|
46
|
+
# associations _assoc_names_ as links and the 'self' link
|
47
|
+
def represent attr_names, assoc_names, base_uri
|
48
|
+
props = {}
|
35
49
|
|
36
|
-
|
37
|
-
|
38
|
-
options.reverse_merge! :in_collection => false,
|
39
|
-
:with_uri => true
|
40
|
-
|
41
|
-
# attributes
|
42
|
-
exposed_attr =
|
43
|
-
options[:in_collection] ? self.class.toast_config.in_collection.exposed_attributes :
|
44
|
-
self.class.toast_config.exposed_attributes
|
45
|
-
|
46
|
-
out = exposed_attr.inject({}) do |acc, attr|
|
47
|
-
acc[attr] = self.send attr
|
48
|
-
acc
|
50
|
+
attr_names.each do |name|
|
51
|
+
props[name] = self.send(name)
|
49
52
|
end
|
50
|
-
|
51
|
-
|
53
|
+
|
54
|
+
assoc_names.each do |name|
|
55
|
+
props[name] = "#{base_uri}#{self.uri_path}/#{name}"
|
56
|
+
end
|
57
|
+
|
58
|
+
props["self"] = base_uri + self.uri_path
|
59
|
+
|
60
|
+
props
|
52
61
|
end
|
53
62
|
end
|
54
63
|
end
|
55
64
|
|
56
|
-
alias acts_as_resource resourceful_model
|
57
|
-
|
58
65
|
# defaults for non resourceful-models
|
59
66
|
def is_resourceful_model?
|
60
67
|
false
|
data/lib/toast/association.rb
CHANGED
@@ -3,8 +3,9 @@ module Toast
|
|
3
3
|
|
4
4
|
attr_reader :model
|
5
5
|
|
6
|
-
def initialize model, id, subresource_name, format
|
7
|
-
|
6
|
+
def initialize model, id, subresource_name, format, config, assoc_model, assoc_config_in, assoc_config_out
|
7
|
+
|
8
|
+
unless config.exposed_associations.include? subresource_name
|
8
9
|
raise ResourceNotFound
|
9
10
|
end
|
10
11
|
|
@@ -13,28 +14,35 @@ module Toast
|
|
13
14
|
@assoc = subresource_name
|
14
15
|
@format = format
|
15
16
|
@is_collection = [:has_many, :has_and_belongs_to_many].include? @model.reflect_on_association(@assoc.to_sym).macro
|
16
|
-
|
17
|
-
@associate_model =
|
18
|
-
@
|
17
|
+
@config = config
|
18
|
+
@associate_model = assoc_model
|
19
|
+
@associate_config_in = assoc_config_in
|
20
|
+
@associate_config_out = assoc_config_out
|
19
21
|
|
20
22
|
end
|
21
23
|
|
22
24
|
def get
|
23
25
|
result = @record.send(@assoc)
|
24
26
|
|
27
|
+
raise ResourceNotFound if result.nil?
|
28
|
+
|
25
29
|
if result.is_a? Array
|
26
30
|
{
|
27
31
|
:json => result.map{|r|
|
28
|
-
r.
|
29
|
-
|
32
|
+
r.represent( @associate_config_out.in_collection.exposed_attributes,
|
33
|
+
@associate_config_out.in_collection.exposed_associations,
|
34
|
+
@base_uri )
|
30
35
|
},
|
31
|
-
:status => :ok
|
36
|
+
:status => :ok,
|
37
|
+
:content_type => @associate_config_out.in_collection.media_type
|
32
38
|
}
|
33
39
|
else
|
34
40
|
{
|
35
|
-
:json =>
|
36
|
-
|
37
|
-
|
41
|
+
:json => result.represent( @associate_config_out.exposed_attributes,
|
42
|
+
@associate_config_out.exposed_associations,
|
43
|
+
@base_uri ),
|
44
|
+
:status => :ok,
|
45
|
+
:content_type => @associate_config_out.media_type
|
38
46
|
}
|
39
47
|
end
|
40
48
|
|
@@ -44,10 +52,10 @@ module Toast
|
|
44
52
|
raise MethodNotAllowed
|
45
53
|
end
|
46
54
|
|
47
|
-
def post payload
|
48
|
-
raise MethodNotAllowed unless @
|
55
|
+
def post payload, media_type
|
56
|
+
raise MethodNotAllowed unless @config.writables.include? @assoc
|
49
57
|
|
50
|
-
if
|
58
|
+
if media_type != @associate_config_in.media_type
|
51
59
|
raise UnsupportedMediaType
|
52
60
|
end
|
53
61
|
|
@@ -63,18 +71,20 @@ module Toast
|
|
63
71
|
|
64
72
|
|
65
73
|
# silently ignore all exposed readable, but not writable fields
|
66
|
-
(@
|
74
|
+
(@associate_config_in.readables - @associate_config_in.writables).each do |rof|
|
67
75
|
payload.delete(rof)
|
68
76
|
end
|
69
77
|
|
70
|
-
|
71
78
|
begin
|
72
79
|
record = @record.send(@assoc).create! payload
|
73
80
|
|
74
81
|
{
|
75
|
-
:json => record.
|
76
|
-
|
77
|
-
|
82
|
+
:json => record.represent( @associate_config_out.exposed_attributes,
|
83
|
+
@associate_config_out.exposed_associations,
|
84
|
+
@base_uri ),
|
85
|
+
:location => self.base_uri + record.uri_path,
|
86
|
+
:status => :created,
|
87
|
+
:content_type => @associate_config_out.media_type
|
78
88
|
}
|
79
89
|
|
80
90
|
rescue ActiveRecord::RecordInvalid => e
|
data/lib/toast/collection.rb
CHANGED
@@ -3,11 +3,11 @@ module Toast
|
|
3
3
|
|
4
4
|
attr_reader :model
|
5
5
|
|
6
|
-
def initialize model, subresource_name, params
|
6
|
+
def initialize model, subresource_name, params, config_in, config_out
|
7
7
|
|
8
8
|
subresource_name ||= "all"
|
9
9
|
|
10
|
-
unless
|
10
|
+
unless config_out.collections.include? subresource_name
|
11
11
|
raise ResourceNotFound
|
12
12
|
end
|
13
13
|
|
@@ -15,11 +15,13 @@ module Toast
|
|
15
15
|
@collection = subresource_name
|
16
16
|
@params = params
|
17
17
|
@format = params[:format]
|
18
|
+
@config_out = config_out
|
19
|
+
@config_in = config_in
|
18
20
|
end
|
19
21
|
|
20
22
|
def get
|
21
23
|
|
22
|
-
records = if @
|
24
|
+
records = if @config_out.pass_params_to.include?(@collection)
|
23
25
|
@model.send(@collection, @params)
|
24
26
|
else
|
25
27
|
@model.send(@collection)
|
@@ -34,10 +36,12 @@ module Toast
|
|
34
36
|
when "json"
|
35
37
|
{
|
36
38
|
:json => records.map{|r|
|
37
|
-
r.
|
38
|
-
|
39
|
+
r.represent( @config_out.in_collection.exposed_attributes,
|
40
|
+
@config_out.in_collection.exposed_associations,
|
41
|
+
@base_uri )
|
39
42
|
},
|
40
|
-
:status => :ok
|
43
|
+
:status => :ok,
|
44
|
+
:content_type => @config_out.in_collection.media_type
|
41
45
|
}
|
42
46
|
else
|
43
47
|
raise ResourceNotFound
|
@@ -48,15 +52,15 @@ module Toast
|
|
48
52
|
raise MethodNotAllowed
|
49
53
|
end
|
50
54
|
|
51
|
-
def post payload
|
52
|
-
raise MethodNotAllowed unless @
|
55
|
+
def post payload, media_type
|
56
|
+
raise MethodNotAllowed unless @config_in.postable?
|
53
57
|
|
54
|
-
if
|
55
|
-
raise
|
58
|
+
if media_type != @config_in.media_type
|
59
|
+
raise UnsupportedMediaType
|
56
60
|
end
|
57
61
|
|
58
|
-
if
|
59
|
-
raise
|
62
|
+
if @collection != "all"
|
63
|
+
raise MethodNotAllowed
|
60
64
|
end
|
61
65
|
|
62
66
|
begin
|
@@ -69,7 +73,7 @@ module Toast
|
|
69
73
|
end
|
70
74
|
|
71
75
|
# silently ignore all exposed readable, but not writable fields
|
72
|
-
(@
|
76
|
+
(@config_in.readables - @config_in.writables + ["self"]).each do |rof|
|
73
77
|
payload.delete(rof)
|
74
78
|
end
|
75
79
|
|
@@ -77,9 +81,12 @@ module Toast
|
|
77
81
|
record = @model.create! payload
|
78
82
|
|
79
83
|
{
|
80
|
-
:json => record.
|
81
|
-
|
82
|
-
|
84
|
+
:json => record.represent( @config_out.exposed_attributes,
|
85
|
+
@config_out.exposed_associations,
|
86
|
+
@base_uri ),
|
87
|
+
:location => @base_uri + record.uri_path,
|
88
|
+
:status => :created,
|
89
|
+
:content_type => @config_out.media_type
|
83
90
|
}
|
84
91
|
|
85
92
|
rescue ActiveRecord::RecordInvalid => e
|
data/lib/toast/config_dsl.rb
CHANGED
@@ -3,7 +3,7 @@ module Toast
|
|
3
3
|
|
4
4
|
class Base
|
5
5
|
include Blockenspiel::DSL
|
6
|
-
dsl_attr_accessor :
|
6
|
+
dsl_attr_accessor :namespace, :media_type
|
7
7
|
|
8
8
|
def initialize model
|
9
9
|
@model = model
|
@@ -11,11 +11,11 @@ module Toast
|
|
11
11
|
@writables = []
|
12
12
|
@collections = []
|
13
13
|
@singles = []
|
14
|
-
@media_type = "application/json"
|
15
14
|
@deletable = false
|
16
15
|
@postable = false
|
17
16
|
@pass_params_to = []
|
18
17
|
@in_collection = ConfigDSL::InCollection.new model, self
|
18
|
+
@media_type = "application/json"
|
19
19
|
end
|
20
20
|
|
21
21
|
def exposed_attributes
|
@@ -107,11 +107,13 @@ module Toast
|
|
107
107
|
class InCollection
|
108
108
|
include Blockenspiel::DSL
|
109
109
|
|
110
|
+
dsl_attr_accessor :media_type
|
111
|
+
|
110
112
|
def initialize model, base_config
|
111
113
|
@model = model
|
114
|
+
@media_type = "application/json"
|
112
115
|
@readables = base_config.readables # must assign a reference
|
113
116
|
@writables = base_config.writables # must assign a reference
|
114
|
-
@media_type = "application/json"
|
115
117
|
end
|
116
118
|
|
117
119
|
def readables= readables
|
@@ -127,13 +129,23 @@ module Toast
|
|
127
129
|
def writables *arg
|
128
130
|
self.writables = 42
|
129
131
|
end
|
130
|
-
|
132
|
+
|
131
133
|
def writables= arg
|
132
134
|
puts
|
133
135
|
puts "Toast Config Warning (#{model.class}): Defining \"writables\" in collection definition has no effect."
|
134
136
|
puts
|
135
137
|
end
|
136
138
|
|
139
|
+
def namespace *arg
|
140
|
+
self.writables = 42
|
141
|
+
end
|
142
|
+
|
143
|
+
def namespace= arg
|
144
|
+
puts
|
145
|
+
puts "Toast Config Warning (#{model.class}): Defining \"namespace\" in collection definition has no effect."
|
146
|
+
puts
|
147
|
+
end
|
148
|
+
|
137
149
|
def exposed_attributes
|
138
150
|
assocs = @model.reflect_on_all_associations.map{|a| a.name.to_s}
|
139
151
|
(@readables + @writables).uniq.select{|f| !assocs.include?(f)}
|
@@ -143,6 +155,7 @@ module Toast
|
|
143
155
|
assocs = @model.reflect_on_all_associations.map{|a| a.name.to_s}
|
144
156
|
(@readables + @writables).uniq.select{|f| assocs.include?(f)}
|
145
157
|
end
|
158
|
+
|
146
159
|
end
|
147
160
|
|
148
161
|
|
data/lib/toast/engine.rb
CHANGED
data/lib/toast/record.rb
CHANGED
@@ -3,22 +3,24 @@ module Toast
|
|
3
3
|
|
4
4
|
attr_reader :model
|
5
5
|
|
6
|
-
def initialize model, id, format
|
6
|
+
def initialize model, id, format, config_in, config_out
|
7
7
|
@model = model
|
8
8
|
@record = model.find(id) rescue raise(ResourceNotFound.new)
|
9
9
|
@format = format
|
10
|
+
@config_in = config_in
|
11
|
+
@config_out = config_out
|
10
12
|
end
|
11
13
|
|
12
|
-
def post payload
|
14
|
+
def post payload, media_type
|
13
15
|
raise MethodNotAllowed
|
14
16
|
end
|
15
17
|
|
16
18
|
# get, put, delete, post return a Hash that can be used as
|
17
19
|
# argument for ActionController#render
|
18
20
|
|
19
|
-
def put payload
|
21
|
+
def put payload, media_type
|
20
22
|
|
21
|
-
if
|
23
|
+
if media_type != @config_in.media_type
|
22
24
|
raise UnsupportedMediaType
|
23
25
|
end
|
24
26
|
|
@@ -33,21 +35,24 @@ module Toast
|
|
33
35
|
end
|
34
36
|
|
35
37
|
# ignore all exposed readable, but not writable fields
|
36
|
-
(@
|
38
|
+
(@config_in.readables - @config_in.writables + ["self"]).each do |rof|
|
37
39
|
payload.delete(rof)
|
38
40
|
end
|
39
|
-
|
41
|
+
|
40
42
|
# set the virtual attributes
|
41
|
-
(
|
43
|
+
(@config_in.writables - @record.attribute_names - @config_in.exposed_associations).each do |vattr|
|
42
44
|
@record.send("#{vattr}=", payload.delete(vattr))
|
43
45
|
end
|
44
|
-
|
46
|
+
|
45
47
|
# mass-update for the rest
|
46
48
|
@record.update_attributes payload
|
47
|
-
{
|
48
|
-
:json => @record.
|
49
|
+
{
|
50
|
+
:json => @record.represent( @config_out.exposed_attributes,
|
51
|
+
@config_out.exposed_associations,
|
52
|
+
@base_uri ),
|
49
53
|
:status => :ok,
|
50
|
-
:location => self.base_uri + @record.
|
54
|
+
:location => self.base_uri + @record.uri_path,
|
55
|
+
:content_type => @config_out.media_type
|
51
56
|
}
|
52
57
|
end
|
53
58
|
|
@@ -60,8 +65,11 @@ module Toast
|
|
60
65
|
}
|
61
66
|
when "json"
|
62
67
|
{
|
63
|
-
:json => @record.
|
64
|
-
|
68
|
+
:json => @record.represent( @config_out.exposed_attributes,
|
69
|
+
@config_out.exposed_associations,
|
70
|
+
@base_uri ),
|
71
|
+
:status => :ok,
|
72
|
+
:content_type => @config_out.media_type
|
65
73
|
}
|
66
74
|
else
|
67
75
|
raise ResourceNotFound
|
@@ -69,7 +77,7 @@ module Toast
|
|
69
77
|
end
|
70
78
|
|
71
79
|
def delete
|
72
|
-
raise MethodNotAllowed unless @
|
80
|
+
raise MethodNotAllowed unless @config_out.deletable?
|
73
81
|
|
74
82
|
@record.destroy
|
75
83
|
{
|
data/lib/toast/resource.rb
CHANGED
@@ -5,12 +5,13 @@ module Toast
|
|
5
5
|
class PayloadInvalid < Exception; end
|
6
6
|
class PayloadFormatError < Exception; end
|
7
7
|
class UnsupportedMediaType < Exception; end
|
8
|
+
class RequestedVersionNotDefined < Exception; end
|
8
9
|
|
9
10
|
# Represents a resource. There are following resource types as sub classes:
|
10
11
|
# Record, Collection, Association, Single
|
11
12
|
class Resource
|
12
13
|
|
13
|
-
attr_accessor :
|
14
|
+
attr_accessor :prefered_media_type, :base_uri, :payload_content_type
|
14
15
|
|
15
16
|
def initialize
|
16
17
|
raise 'ToastResource#new: use #build to create an instance'
|
@@ -22,25 +23,56 @@ module Toast
|
|
22
23
|
subresource_name = params[:subresource]
|
23
24
|
format = params[:format]
|
24
25
|
|
25
|
-
|
26
|
+
#### Debugging stop
|
27
|
+
# binding.pry if $halt
|
28
|
+
###
|
26
29
|
|
30
|
+
begin
|
31
|
+
|
32
|
+
# determine model
|
27
33
|
model = get_class_by_resource_name resource_name
|
28
|
-
|
29
|
-
#
|
30
|
-
|
31
|
-
|
34
|
+
|
35
|
+
# determine config for representation
|
36
|
+
# config_in: cosumed representation
|
37
|
+
# config_out: produced representation
|
38
|
+
config_out = model.toast_config request.accept_media_types.prefered
|
39
|
+
config_in = model.toast_config request.media_type
|
40
|
+
|
41
|
+
# ... or in case of an association request
|
42
|
+
config_assoc_src = model.toast_config request.headers["Assoc-source-type"]
|
43
|
+
|
44
|
+
# base URI for returned object
|
45
|
+
base_uri = request.base_url + request.script_name +
|
46
|
+
(config_out.namespace ? "/" + config_out.namespace : "")
|
47
|
+
|
48
|
+
# decide which sub resource type
|
49
|
+
rsc = if id.nil? and config_out.singles.include?(subresource_name)
|
50
|
+
Toast::Single.new(model, subresource_name, params.clone, config_in, config_out)
|
32
51
|
elsif id.nil?
|
33
|
-
Toast::Collection.new(model, subresource_name, params.clone)
|
52
|
+
Toast::Collection.new(model, subresource_name, params.clone, config_in, config_out)
|
34
53
|
elsif subresource_name.nil?
|
35
|
-
Toast::Record.new(model, id, format)
|
36
|
-
elsif
|
37
|
-
|
54
|
+
Toast::Record.new(model, id, format, config_in, config_out)
|
55
|
+
elsif (config_assoc_src && config_assoc_src.exposed_associations.include?(subresource_name))
|
56
|
+
|
57
|
+
# determine associated model
|
58
|
+
assoc_model = get_class_by_resource_name subresource_name
|
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
|
+
Toast::Association.new(model, id, subresource_name, format, config_assoc_src,
|
69
|
+
assoc_model, assoc_config_in, assoc_config_out)
|
38
70
|
else
|
39
71
|
raise ResourceNotFound
|
40
72
|
end
|
41
73
|
|
42
|
-
|
43
|
-
rsc.base_uri =
|
74
|
+
# set base to be prepended to URIs
|
75
|
+
rsc.base_uri = base_uri
|
44
76
|
|
45
77
|
rsc
|
46
78
|
rescue NameError
|
@@ -63,10 +95,10 @@ module Toast
|
|
63
95
|
end
|
64
96
|
end
|
65
97
|
|
66
|
-
def apply method, payload
|
98
|
+
def apply method, payload, payload_media_type
|
67
99
|
case method
|
68
|
-
when "PUT","POST"
|
69
|
-
self.send(method.downcase, payload)
|
100
|
+
when "PUT","POST"
|
101
|
+
self.send(method.downcase, payload, payload_media_type)
|
70
102
|
when "DELETE","GET"
|
71
103
|
self.send(method.downcase)
|
72
104
|
else
|
@@ -83,10 +115,10 @@ module Toast
|
|
83
115
|
record.class.toast_config.exposed_associations
|
84
116
|
|
85
117
|
exposed_assoc.each do |assoc|
|
86
|
-
out[assoc] = "#{self.base_uri}#{record.
|
118
|
+
out[assoc] = "#{self.base_uri}#{record.uri_path}/#{assoc}"
|
87
119
|
end
|
88
120
|
|
89
|
-
out["
|
121
|
+
out["self"] = self.base_uri + record.uri_path
|
90
122
|
|
91
123
|
out
|
92
124
|
end
|
data/lib/toast/single.rb
CHANGED
@@ -13,9 +13,11 @@ module Toast
|
|
13
13
|
|
14
14
|
attr_reader :model
|
15
15
|
|
16
|
-
def initialize model, subresource_name, params
|
16
|
+
def initialize model, subresource_name, params, config_in, config_out
|
17
|
+
@config_in = config_in
|
18
|
+
@config_out = config_out
|
17
19
|
|
18
|
-
unless
|
20
|
+
unless @config_out.singles.include? subresource_name
|
19
21
|
raise ResourceNotFound
|
20
22
|
end
|
21
23
|
|
@@ -23,14 +25,14 @@ module Toast
|
|
23
25
|
@params = params
|
24
26
|
@format = params[:format]
|
25
27
|
|
26
|
-
|
28
|
+
|
29
|
+
@record = if @config_out.pass_params_to.include?(subresource_name)
|
27
30
|
@model.send(subresource_name, @params)
|
28
31
|
else
|
29
32
|
@model.send(subresource_name)
|
30
33
|
end
|
31
|
-
|
32
|
-
raise ResourceNotFound if @record.nil?
|
33
|
-
|
34
|
+
|
35
|
+
raise ResourceNotFound if @record.nil?
|
34
36
|
end
|
35
37
|
|
36
38
|
def get
|
@@ -42,7 +44,9 @@ module Toast
|
|
42
44
|
}
|
43
45
|
when "json"
|
44
46
|
{
|
45
|
-
:json => @record.
|
47
|
+
:json => @record.represent( @config_out.exposed_attributes,
|
48
|
+
@config_out.exposed_associations,
|
49
|
+
@base_uri ),
|
46
50
|
:status => :ok
|
47
51
|
}
|
48
52
|
else
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 6
|
8
|
+
- 0
|
9
|
+
version: 0.6.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Robert Annies
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-05-31 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -31,6 +31,19 @@ dependencies:
|
|
31
31
|
version: 0.4.2
|
32
32
|
type: :runtime
|
33
33
|
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rack-accept-media-types
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 9
|
44
|
+
version: "0.9"
|
45
|
+
type: :runtime
|
46
|
+
version_requirements: *id002
|
34
47
|
description: |-
|
35
48
|
Toast is an extension to Ruby on Rails that lets you expose any
|
36
49
|
ActiveRecord model as a resource according to the REST paradigm. The
|