rest_framework 0.0.9 → 0.0.15

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.
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