rest_framework 0.0.9 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce317c05e27ab6421b18f37595dbb846a747c8616d19fc9a1927a9ecc30fefc7
4
- data.tar.gz: b8f88631bfca835f395677af0e0c0079b40c079aa8d9a6cc8c8ee46dc5d589c2
3
+ metadata.gz: 70c2eb85612656cf6f1b3d34b97deb06ad01aa07459012b4254e543fc0bd5507
4
+ data.tar.gz: 76f44db8c396cfe5bb539faebb6f6031276d7133327b733cab4a645922176d95
5
5
  SHA512:
6
- metadata.gz: abd9fc1e83d61c60af77d834d3a3e03a4a904863f3ad4bb851d8cf35a5a563a322eef508a273764ce727303e3e25f526cca03a643127957a7d9952e4988de743
7
- data.tar.gz: 8aadf4ba5467c645da2404df61880bd741a491eea0c14a09b20e7056726022f7fc7bd4b8a3f90e9ac068b578e63870c85cfaa813296245cf8c4fddfb7d002a66
6
+ metadata.gz: 246bd5c3972c212c1d6fcf600da1c894fe05acaeda8596d432b6b360e265520b3e54f3b4842998c26868464c29bd79f3c164f51104145163c0a63ba9e94f06fb
7
+ data.tar.gz: 52af9985b986a167f70cd8def492a3ff2c7d61bafd48e120f49934cc3827f76a1e6dbc5c02651df6bba7fdd622be058f945534415d6cb74e3537c56f9c18c0e2
@@ -19,7 +19,7 @@
19
19
  <div class="container py-3">
20
20
  <div class="container">
21
21
  <div class="row">
22
- <h1><%= @title %></h1>
22
+ <h1><%= (@header_text if defined? @header_text) || @title %></h1>
23
23
  </div>
24
24
  <hr/>
25
25
  <% if @json_payload || @xml_payload %>
@@ -46,7 +46,7 @@
46
46
  <div class="tab-content w-100 pt-3">
47
47
  <div class="tab-pane fade show active" id="tab-json" role="tab">
48
48
  <% if @json_payload %>
49
- <div><pre><code class="language-json"><%= JSON.pretty_generate(JSON.parse(@json_payload)) %></code></pre></div>
49
+ <div><pre><code class="language-json"><%= JSON.pretty_generate(JSON.parse(@json_payload)) unless @json_payload == '' %></code></pre></div>
50
50
  <% end %>
51
51
  </div>
52
52
  <div class="tab-pane fade" id="tab-xml" role="tab">
@@ -1 +1 @@
1
- 0.0.9
1
+ 0.0.15
@@ -34,6 +34,11 @@ module RESTFramework
34
34
  :skip_actions,
35
35
  :paginator_class,
36
36
  ])
37
+
38
+ # skip csrf since this is an API
39
+ base.skip_before_action(:verify_authenticity_token) rescue nil
40
+
41
+ # handle some common exceptions
37
42
  base.rescue_from(ActiveRecord::RecordNotFound, with: :record_not_found)
38
43
  base.rescue_from(ActiveRecord::RecordInvalid, with: :record_invalid)
39
44
  base.rescue_from(ActiveRecord::RecordNotSaved, with: :record_not_saved)
@@ -69,40 +74,47 @@ module RESTFramework
69
74
  end
70
75
  return ActionDispatch::Routing::RoutesInspector.new(Rails.application.routes.routes).format(
71
76
  formatter.new
72
- ).lines[1..].map { |r| r.split.last(3) }.map { |r|
77
+ ).lines.drop(1).map { |r| r.split.last(3) }.map { |r|
73
78
  {verb: r[0], path: r[1], action: r[2]}
74
79
  }.select { |r| r[:path].start_with?(request.path) }
75
80
  end
76
81
 
77
- # Helper alias for `respond_to`/`render`, and replace nil responses with blank ones. `payload`
78
- # must be already serialized to Ruby primitives.
82
+ # Helper alias for `respond_to`/`render`. `payload` should be already serialized to Ruby
83
+ # primitives.
79
84
  def api_response(payload, html_kwargs: nil, json_kwargs: nil, xml_kwargs: nil, **kwargs)
80
85
  html_kwargs ||= {}
81
86
  json_kwargs ||= {}
82
87
  xml_kwargs ||= {}
83
88
 
84
- # make empty responses status 204 unless a status is already explicitly defined
85
- if (payload.nil? || payload == '') && !kwargs.key?(:status)
86
- kwargs[:status] = 204
87
- end
89
+ # allow blank (no-content) responses
90
+ @blank = kwargs[:blank]
88
91
 
89
92
  respond_to do |format|
90
- if payload.respond_to?(:to_json)
91
- format.json {
92
- kwargs = kwargs.merge(json_kwargs)
93
- render(json: payload || '', **kwargs)
94
- }
95
- end
96
- if payload.respond_to?(:to_xml)
97
- format.xml {
98
- kwargs = kwargs.merge(xml_kwargs)
99
- render(xml: payload || '', **kwargs)
100
- }
93
+ if @blank
94
+ format.json {head :no_content}
95
+ format.xml {head :no_content}
96
+ else
97
+ if payload.respond_to?(:to_json)
98
+ format.json {
99
+ kwargs = kwargs.merge(json_kwargs)
100
+ render(json: payload, layout: false, **kwargs)
101
+ }
102
+ end
103
+ if payload.respond_to?(:to_xml)
104
+ format.xml {
105
+ kwargs = kwargs.merge(xml_kwargs)
106
+ render(xml: payload, layout: false, **kwargs)
107
+ }
108
+ end
101
109
  end
102
110
  format.html {
103
111
  @payload = payload
104
- @json_payload = payload.to_json
105
- @xml_payload = payload.to_xml
112
+ @json_payload = ''
113
+ @xml_payload = ''
114
+ unless @blank
115
+ @json_payload = payload.to_json if payload.respond_to?(:to_json)
116
+ @xml_payload = payload.to_xml if payload.respond_to?(:to_xml)
117
+ end
106
118
  @template_logo_text ||= "Rails REST Framework"
107
119
  @title ||= self.controller_name.camelize
108
120
  @routes ||= self._get_routes
@@ -20,6 +20,7 @@ module RESTFramework
20
20
  :allowed_action_parameters,
21
21
  :serializer_class,
22
22
  :extra_member_actions,
23
+ :disable_creation_from_recordset,
23
24
  ])
24
25
  base.alias_method(:extra_collection_actions=, :extra_actions=)
25
26
  end
@@ -31,49 +32,43 @@ module RESTFramework
31
32
  return self.class.serializer_class || NativeModelSerializer
32
33
  end
33
34
 
34
- # Get a list of fields for an action (or the current action if none given).
35
- def get_fields(action: nil)
35
+ # Get a list of fields for the current action.
36
+ def get_fields
36
37
  action_fields = self.class.action_fields || {}
37
-
38
- # action will, by default, be the current action name
39
- action = action_name.to_sym unless action
38
+ action = self.action_name.to_sym
40
39
 
41
40
  # index action should use :list fields if :index is not provided
42
41
  action = :list if action == :index && !action_fields.key?(:index)
43
42
 
44
- return action_fields[action] || self.class.fields || []
43
+ return (action_fields[action] if action) || self.class.fields || []
45
44
  end
46
45
 
47
- # Get a native serializer config for an action (or the current action if none given).
48
- def get_native_serializer_config(action: nil)
49
- native_serializer_action_config = self.class.native_serializer_action_config || {}
50
-
51
- # action will, by default, be the current action name
52
- action = action_name.to_sym unless action
46
+ # Get a native serializer config for the current action.
47
+ def get_native_serializer_config
48
+ action_serializer_config = self.class.native_serializer_action_config || {}
49
+ action = self.action_name.to_sym
53
50
 
54
51
  # index action should use :list serializer config if :index is not provided
55
- action = :list if action == :index && !native_serializer_action_config.key?(:index)
52
+ action = :list if action == :index && !action_serializer_config.key?(:index)
56
53
 
57
- return native_serializer_action_config[action] || self.class.native_serializer_config
54
+ return (action_serializer_config[action] if action) || self.class.native_serializer_config
58
55
  end
59
56
 
60
- # Get a list of parameters allowed for an action (or the current action if none given).
61
- def get_allowed_parameters(action: nil)
57
+ # Get a list of parameters allowed for the current action.
58
+ def get_allowed_parameters
62
59
  allowed_action_parameters = self.class.allowed_action_parameters || {}
63
-
64
- # action will, by default, be the current action name
65
- action = action_name.to_sym unless action
60
+ action = self.action_name.to_sym
66
61
 
67
62
  # index action should use :list allowed parameters if :index is not provided
68
63
  action = :list if action == :index && !allowed_action_parameters.key?(:index)
69
64
 
70
- return allowed_action_parameters[action] || self.class.allowed_parameters
65
+ return (allowed_action_parameters[action] if action) || self.class.allowed_parameters
71
66
  end
72
67
 
73
68
  # Filter the request body for keys in current action's allowed_parameters/fields config.
74
69
  def _get_parameter_values_from_request_body
75
70
  fields = self.get_allowed_parameters || self.get_fields
76
- return @_get_field_values_from_request_body ||= (request.request_parameters.select { |p|
71
+ return @_get_parameter_values_from_request_body ||= (request.request_parameters.select { |p|
77
72
  fields.include?(p.to_sym) || fields.include?(p.to_s)
78
73
  })
79
74
  end
@@ -83,7 +78,7 @@ module RESTFramework
83
78
  # Filter params for keys allowed by the current action's filterset_fields/fields config.
84
79
  def _get_filterset_values_from_params
85
80
  fields = self.filterset_fields || self.get_fields
86
- return @_get_field_values_from_params ||= request.query_parameters.select { |p|
81
+ return @_get_filterset_values_from_params ||= request.query_parameters.select { |p|
87
82
  fields.include?(p.to_sym) || fields.include?(p.to_s)
88
83
  }
89
84
  end
@@ -171,7 +166,13 @@ module RESTFramework
171
166
 
172
167
  module CreateModelMixin
173
168
  def create
174
- @record = self.get_model.create!(self.get_create_params)
169
+ if self.get_recordset.respond_to?(:create!) && !self.disable_creation_from_recordset
170
+ # Create with any properties inherited from the recordset (like associations).
171
+ @record = self.get_recordset.create!(self.get_create_params)
172
+ else
173
+ # Otherwise, perform a "bare" create.
174
+ @record = self.get_model.create!(self.get_create_params)
175
+ end
175
176
  @serialized_record = self.get_serializer_class.new(
176
177
  object: @record, controller: self
177
178
  ).serialize
@@ -7,29 +7,59 @@ module RESTFramework
7
7
  @data = data
8
8
  @controller = controller
9
9
  end
10
-
11
- def is_valid
12
- return true
13
- end
14
10
  end
15
11
 
16
12
  # This serializer uses `.as_json` to serialize objects. Despite the name, `.as_json` is a Rails
17
13
  # method which converts objects to Ruby primitives (with the top-level being either an array or a
18
14
  # hash).
19
15
  class NativeModelSerializer < BaseSerializer
20
- def initialize(model: nil, **kwargs)
16
+ class_attribute :config
17
+ class_attribute :singular_config
18
+ class_attribute :plural_config
19
+ class_attribute :action_config
20
+
21
+ def initialize(model: nil, many: nil, **kwargs)
21
22
  super(**kwargs)
22
- @model = model || @controller.send(:get_model)
23
+ @many = many
24
+ @model = model || (@controller ? @controller.send(:get_model) : nil)
25
+ end
26
+
27
+ # Get controller action, if possible.
28
+ def get_action
29
+ return @controller&.action_name&.to_sym
30
+ end
31
+
32
+ # Get a locally defined configuration, if one is defined.
33
+ def get_local_serializer_config
34
+ action = self.get_action
35
+
36
+ if action && self.action_config
37
+ # index action should use :list serializer config if :index is not provided
38
+ action = :list if action == :index && !self.action_config.key?(:index)
39
+
40
+ return self.action_config[action] if self.action_config[action]
41
+ end
42
+
43
+ # no action_config, so try singular/plural config
44
+ return self.plural_config if @many && self.plural_config
45
+ return self.singular_config if !@many && self.singular_config
46
+
47
+ # lastly, try the default config
48
+ return self.config
23
49
  end
24
50
 
25
51
  # Get a configuration passable to `as_json` for the model.
26
- def get_native_serializer_config
52
+ def get_serializer_config
53
+ # return a locally defined serializer config if one is defined
54
+ local_config = self.get_local_serializer_config
55
+ return local_config if local_config
56
+
27
57
  # return a serializer config if one is defined
28
58
  serializer_config = @controller.send(:get_native_serializer_config)
29
59
  return serializer_config if serializer_config
30
60
 
31
- # build serializer config from fields
32
- fields = @controller.send(:get_fields)
61
+ # otherwise, build a serializer config from fields
62
+ fields = @controller.send(:get_fields) if @controller
33
63
  unless fields.blank?
34
64
  columns, methods = fields.partition { |f| f.to_s.in?(@model.column_names) }
35
65
  return {only: columns, methods: methods}
@@ -41,9 +71,38 @@ module RESTFramework
41
71
  # Convert the object(s) to Ruby primitives.
42
72
  def serialize
43
73
  if @object
44
- return @object.as_json(self.get_native_serializer_config)
74
+ @many = @object.respond_to?(:each) if @many.nil?
75
+ return @object.as_json(self.get_serializer_config)
45
76
  end
46
77
  return nil
47
78
  end
79
+
80
+ # Allow a serializer instance to be used as a hash directly in a nested serializer config.
81
+ def [](key)
82
+ unless instance_variable_defined?(:@_nested_config)
83
+ @_nested_config = self.get_serializer_config
84
+ end
85
+ return @_nested_config[key]
86
+ end
87
+ def []=(key, value)
88
+ unless instance_variable_defined?(:@_nested_config)
89
+ @_nested_config = self.get_serializer_config
90
+ end
91
+ return @_nested_config[key] = value
92
+ end
93
+
94
+ # Allow a serializer class to be used as a hash directly in a nested serializer config.
95
+ def self.[](key)
96
+ unless instance_variable_defined?(:@_nested_config)
97
+ @_nested_config = self.new.get_serializer_config
98
+ end
99
+ return @_nested_config[key]
100
+ end
101
+ def self.[]=(key, value)
102
+ unless instance_variable_defined?(:@_nested_config)
103
+ @_nested_config = self.new.get_serializer_config
104
+ end
105
+ return @_nested_config[key] = value
106
+ end
48
107
  end
49
108
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest_framework
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregory N. Schmit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-06 00:00:00.000000000 Z
11
+ date: 2020-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails