rest_framework 0.0.15 → 0.0.16

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: 70c2eb85612656cf6f1b3d34b97deb06ad01aa07459012b4254e543fc0bd5507
4
- data.tar.gz: 76f44db8c396cfe5bb539faebb6f6031276d7133327b733cab4a645922176d95
3
+ metadata.gz: 825e7e7ac0e9c8ae57250288a54dc3ef6510665ce3d4fee23245c559aa8e8233
4
+ data.tar.gz: 2211c303d14708ef94a4cb35d6e3b25bf78b3b08645f2990ca5448354d8dd64e
5
5
  SHA512:
6
- metadata.gz: 246bd5c3972c212c1d6fcf600da1c894fe05acaeda8596d432b6b360e265520b3e54f3b4842998c26868464c29bd79f3c164f51104145163c0a63ba9e94f06fb
7
- data.tar.gz: 52af9985b986a167f70cd8def492a3ff2c7d61bafd48e120f49934cc3827f76a1e6dbc5c02651df6bba7fdd622be058f945534415d6cb74e3537c56f9c18c0e2
6
+ metadata.gz: 0ee2cf406f2b8d77d9ea63650b080d037a759143e0a3e19846585d493a386a4647db0fe59188aa0fd887257a18087aaca82b80d99dee962af1dfdb7eca66a07c
7
+ data.tar.gz: 6248caea5ad7f5a37a55f7da6aae55c70dc284b9f04d046fc6149a13dff4ae34410106c97f54274f59a8353c79fe97073b7dcba51d65d9c94eb0f9cff1a205ac
data/README.md CHANGED
@@ -116,18 +116,5 @@ To run the full test suite:
116
116
  $ rake test
117
117
  ```
118
118
 
119
- To run unit tests:
120
-
121
- ```shell
122
- $ rake test:unit
123
- ```
124
-
125
- To run integration tests:
126
-
127
- ```shell
128
- $ rake test:integration
129
- ```
130
-
131
- To interact with the integration app, you can `cd test/integration` and operate it via the normal
132
- Rails interfaces. Ensure you run `rake db:schema:load` before running `rails server` or
133
- `rails console`.
119
+ To interact with the test app, `cd test` and operate it via the normal Rails interfaces. Ensure you
120
+ run `rake db:schema:load` before running `rails server` or `rails console`.
@@ -30,14 +30,14 @@
30
30
  <% if @json_payload %>
31
31
  <li class="nav-item">
32
32
  <a class="nav-link active" href="#tab-json" data-toggle="tab" role="tab">
33
- JSON
33
+ .json
34
34
  </a>
35
35
  </li>
36
36
  <% end %>
37
37
  <% if @xml_payload %>
38
38
  <li class="nav-item">
39
39
  <a class="nav-link" href="#tab-xml" data-toggle="tab" role="tab">
40
- XML
40
+ .xml
41
41
  </a>
42
42
  </li>
43
43
  <% end %>
@@ -3,5 +3,8 @@ end
3
3
 
4
4
  require_relative "rest_framework/controller_mixins"
5
5
  require_relative "rest_framework/engine"
6
+ require_relative "rest_framework/filters"
7
+ require_relative "rest_framework/paginators"
6
8
  require_relative "rest_framework/routers"
9
+ require_relative "rest_framework/serializers"
7
10
  require_relative "rest_framework/version"
@@ -1 +1 @@
1
- 0.0.15
1
+ 0.0.16
@@ -1,3 +1,5 @@
1
+ require_relative '../serializers'
2
+
1
3
  module RESTFramework
2
4
 
3
5
  # This module provides the common functionality for any controller mixins, a `root` action, and
@@ -28,12 +30,37 @@ module RESTFramework
28
30
  def self.included(base)
29
31
  if base.is_a? Class
30
32
  base.extend ClassMethods
31
- base.class_attribute(*[
32
- :singleton_controller,
33
- :extra_actions,
34
- :skip_actions,
35
- :paginator_class,
36
- ])
33
+
34
+ # Add class attributes (with defaults) unless they already exist.
35
+ {
36
+ extra_actions: nil,
37
+ extra_member_actions: nil,
38
+ filter_backends: nil,
39
+ native_serializer_config: nil,
40
+ native_serializer_action_config: nil,
41
+ paginator_class: nil,
42
+ page_size: nil,
43
+ page_query_param: 'page',
44
+ page_size_query_param: 'page_size',
45
+ max_page_size: nil,
46
+ serializer_class: nil,
47
+ singleton_controller: nil,
48
+ skip_actions: nil,
49
+ }.each do |a, default|
50
+ unless base.respond_to?(a)
51
+ base.class_attribute(a)
52
+
53
+ # Set default manually so we can still support Rails 4. Maybe later we can use the
54
+ # default parameter on `class_attribute`.
55
+ base.send(:"#{a}=", default)
56
+ end
57
+ end
58
+
59
+ # Alias `extra_actions` to `extra_collection_actions`.
60
+ unless base.respond_to?(:extra_collection_actions)
61
+ base.alias_method(:extra_collection_actions, :extra_actions)
62
+ base.alias_method(:extra_collection_actions=, :extra_actions=)
63
+ end
37
64
 
38
65
  # skip csrf since this is an API
39
66
  base.skip_before_action(:verify_authenticity_token) rescue nil
@@ -48,6 +75,45 @@ module RESTFramework
48
75
 
49
76
  protected
50
77
 
78
+ # Helper to get filtering backends with a sane default.
79
+ def get_filter_backends
80
+ if self.class.filter_backends
81
+ return self.class.filter_backends
82
+ end
83
+
84
+ # By default, return nil.
85
+ return nil
86
+ end
87
+
88
+ # Filter the recordset over all configured filter backends.
89
+ def get_filtered_data(data)
90
+ (self.get_filter_backends || []).each do |filter_class|
91
+ filter = filter_class.new(controller: self)
92
+ data = filter.get_filtered_data(data)
93
+ end
94
+
95
+ return data
96
+ end
97
+
98
+ # Helper to get the configured serializer class, or `NativeModelSerializer` as a default.
99
+ def get_serializer_class
100
+ return self.class.serializer_class || NativeModelSerializer
101
+ end
102
+
103
+ # Get a native serializer config for the current action.
104
+ def get_native_serializer_config
105
+ action_serializer_config = self.class.native_serializer_action_config || {}
106
+ action = self.action_name.to_sym
107
+
108
+ # Handle case where :index action is not defined.
109
+ if action == :index && !action_serializer_config.key?(:index)
110
+ # Default is :show if `singleton_controller`, otherwise :list.
111
+ action = self.class.singleton_controller ? :show : :list
112
+ end
113
+
114
+ return (action_serializer_config[action] if action) || self.class.native_serializer_config
115
+ end
116
+
51
117
  def record_invalid(e)
52
118
  return api_response(
53
119
  {message: "Record invalid.", exception: e, errors: e.record.errors}, status: 400
@@ -66,6 +132,7 @@ module RESTFramework
66
132
  return api_response({message: "Record not destroyed.", exception: e}, status: 406)
67
133
  end
68
134
 
135
+ # Helper for showing routes under a controller action, used for the browsable API.
69
136
  def _get_routes
70
137
  begin
71
138
  formatter = ActionDispatch::Routing::ConsoleFormatter::Sheet
@@ -124,8 +191,8 @@ module RESTFramework
124
191
  rescue ActionView::MissingTemplate # fallback to rest_framework layout/view
125
192
  kwargs[:layout] = "rest_framework"
126
193
  kwargs[:template] = "rest_framework/default"
194
+ render(**kwargs)
127
195
  end
128
- render(**kwargs)
129
196
  }
130
197
  end
131
198
  end
@@ -1,5 +1,5 @@
1
1
  require_relative 'base'
2
- require_relative '../serializers'
2
+ require_relative '../filters'
3
3
 
4
4
  module RESTFramework
5
5
 
@@ -8,61 +8,71 @@ module RESTFramework
8
8
  def self.included(base)
9
9
  if base.is_a? Class
10
10
  BaseControllerMixin.included(base)
11
- base.class_attribute(*[
12
- :model,
13
- :recordset,
14
- :fields,
15
- :action_fields,
16
- :native_serializer_config,
17
- :native_serializer_action_config,
18
- :filterset_fields,
19
- :allowed_parameters,
20
- :allowed_action_parameters,
21
- :serializer_class,
22
- :extra_member_actions,
23
- :disable_creation_from_recordset,
24
- ])
25
- base.alias_method(:extra_collection_actions=, :extra_actions=)
11
+
12
+ # Add class attributes (with defaults) unless they already exist.
13
+ {
14
+ # Core attributes related to models.
15
+ model: nil,
16
+ recordset: nil,
17
+
18
+ # Attributes for create/update parameters.
19
+ allowed_parameters: nil,
20
+ allowed_action_parameters: nil,
21
+
22
+ # Attributes for configuring record fields.
23
+ fields: nil,
24
+ action_fields: nil,
25
+
26
+ # Attributes for default model filtering (and ordering).
27
+ filterset_fields: nil,
28
+ ordering_fields: nil,
29
+ ordering_query_param: 'ordering',
30
+
31
+ # Other misc attributes.
32
+ disable_creation_from_recordset: nil, # Option to disable `recordset.create` behavior.
33
+ }.each do |a, default|
34
+ unless base.respond_to?(a)
35
+ base.class_attribute(a)
36
+
37
+ # Set default manually so we can still support Rails 4. Maybe later we can use the
38
+ # default parameter on `class_attribute`.
39
+ base.send(:"#{a}=", default)
40
+ end
41
+ end
26
42
  end
27
43
  end
28
44
 
29
45
  protected
30
46
 
31
- def get_serializer_class
32
- return self.class.serializer_class || NativeModelSerializer
33
- end
34
-
35
- # Get a list of fields for the current action.
36
- def get_fields
37
- action_fields = self.class.action_fields || {}
47
+ # Get a list of parameters allowed for the current action.
48
+ def get_allowed_parameters
49
+ allowed_action_parameters = self.class.allowed_action_parameters || {}
38
50
  action = self.action_name.to_sym
39
51
 
40
- # index action should use :list fields if :index is not provided
41
- action = :list if action == :index && !action_fields.key?(:index)
52
+ # index action should use :list allowed parameters if :index is not provided
53
+ action = :list if action == :index && !allowed_action_parameters.key?(:index)
42
54
 
43
- return (action_fields[action] if action) || self.class.fields || []
55
+ return (allowed_action_parameters[action] if action) || self.class.allowed_parameters
44
56
  end
45
57
 
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
50
-
51
- # index action should use :list serializer config if :index is not provided
52
- action = :list if action == :index && !action_serializer_config.key?(:index)
58
+ # Get the list of filtering backends to use.
59
+ def get_filter_backends
60
+ backends = super
61
+ return backends if backends
53
62
 
54
- return (action_serializer_config[action] if action) || self.class.native_serializer_config
63
+ # By default, return the standard model filter backend.
64
+ return [RESTFramework::ModelFilter, RESTFramework::ModelOrderingFilter]
55
65
  end
56
66
 
57
- # Get a list of parameters allowed for the current action.
58
- def get_allowed_parameters
59
- allowed_action_parameters = self.class.allowed_action_parameters || {}
67
+ # Get a list of fields for the current action.
68
+ def get_fields
69
+ action_fields = self.class.action_fields || {}
60
70
  action = self.action_name.to_sym
61
71
 
62
- # index action should use :list allowed parameters if :index is not provided
63
- action = :list if action == :index && !allowed_action_parameters.key?(:index)
72
+ # index action should use :list fields if :index is not provided
73
+ action = :list if action == :index && !action_fields.key?(:index)
64
74
 
65
- return (allowed_action_parameters[action] if action) || self.class.allowed_parameters
75
+ return (action_fields[action] if action) || self.class.fields || []
66
76
  end
67
77
 
68
78
  # Filter the request body for keys in current action's allowed_parameters/fields config.
@@ -75,29 +85,10 @@ module RESTFramework
75
85
  alias :get_create_params :_get_parameter_values_from_request_body
76
86
  alias :get_update_params :_get_parameter_values_from_request_body
77
87
 
78
- # Filter params for keys allowed by the current action's filterset_fields/fields config.
79
- def _get_filterset_values_from_params
80
- fields = self.filterset_fields || self.get_fields
81
- return @_get_filterset_values_from_params ||= request.query_parameters.select { |p|
82
- fields.include?(p.to_sym) || fields.include?(p.to_s)
83
- }
84
- end
85
- alias :get_lookup_params :_get_filterset_values_from_params
86
- alias :get_filter_params :_get_filterset_values_from_params
87
-
88
- # Get the recordset, filtered by the filter params.
89
- def get_filtered_recordset
90
- filter_params = self.get_filter_params
91
- unless filter_params.blank?
92
- return self.get_recordset.where(**self.get_filter_params.to_hash.symbolize_keys)
93
- end
94
- return self.get_recordset
95
- end
96
-
97
88
  # Get a record by `id` or return a single record if recordset is filtered down to a single
98
89
  # record.
99
90
  def get_record
100
- records = self.get_filtered_recordset
91
+ records = self.get_filtered_data(self.get_recordset)
101
92
  if params['id'] # direct lookup
102
93
  return records.find(params['id'])
103
94
  elsif records.length == 1
@@ -144,23 +135,28 @@ module RESTFramework
144
135
  end
145
136
 
146
137
  module ListModelMixin
147
- # TODO: pagination classes like Django
148
138
  def index
149
- @records = self.get_filtered_recordset
150
- @serialized_records = self.get_serializer_class.new(
151
- object: @records, controller: self
152
- ).serialize
153
- return api_response(@serialized_records)
139
+ @records = self.get_filtered_data(self.get_recordset)
140
+
141
+ # Handle pagination, if enabled.
142
+ if self.class.paginator_class
143
+ paginator = self.class.paginator_class.new(data: @records, controller: self)
144
+ page = paginator.get_page
145
+ serialized_page = self.get_serializer_class.new(object: page, controller: self).serialize
146
+ data = paginator.get_paginated_response(serialized_page)
147
+ else
148
+ data = self.get_serializer_class.new(object: @records, controller: self).serialize
149
+ end
150
+
151
+ return api_response(data)
154
152
  end
155
153
  end
156
154
 
157
155
  module ShowModelMixin
158
156
  def show
159
157
  @record = self.get_record
160
- @serialized_record = self.get_serializer_class.new(
161
- object: @record, controller: self
162
- ).serialize
163
- return api_response(@serialized_record)
158
+ serialized_record = self.get_serializer_class.new(object: @record, controller: self).serialize
159
+ return api_response(serialized_record)
164
160
  end
165
161
  end
166
162
 
@@ -173,10 +169,8 @@ module RESTFramework
173
169
  # Otherwise, perform a "bare" create.
174
170
  @record = self.get_model.create!(self.get_create_params)
175
171
  end
176
- @serialized_record = self.get_serializer_class.new(
177
- object: @record, controller: self
178
- ).serialize
179
- return api_response(@serialized_record)
172
+ serialized_record = self.get_serializer_class.new(object: @record, controller: self).serialize
173
+ return api_response(serialized_record)
180
174
  end
181
175
  end
182
176
 
@@ -184,10 +178,8 @@ module RESTFramework
184
178
  def update
185
179
  @record = self.get_record
186
180
  @record.update!(self.get_update_params)
187
- @serialized_record = self.get_serializer_class.new(
188
- object: @record, controller: self
189
- ).serialize
190
- return api_response(@serialized_record)
181
+ serialized_record = self.get_serializer_class.new(object: @record, controller: self).serialize
182
+ return api_response(serialized_record)
191
183
  end
192
184
  end
193
185
 
@@ -0,0 +1,65 @@
1
+ module RESTFramework
2
+ class BaseFilter
3
+ def initialize(controller:)
4
+ @controller = controller
5
+ end
6
+
7
+ def get_filtered_data(data)
8
+ raise NotImplementedError
9
+ end
10
+ end
11
+
12
+ # A simple filtering backend that supports filtering a recordset based on fields defined on the
13
+ # controller class.
14
+ class ModelFilter < BaseFilter
15
+ # Filter params for keys allowed by the current action's filterset_fields/fields config.
16
+ def _get_filter_params
17
+ fields = @controller.class.filterset_fields || @controller.send(:get_fields)
18
+ return @controller.request.query_parameters.select { |p|
19
+ fields.include?(p.to_sym) || fields.include?(p.to_s)
20
+ }.to_hash.symbolize_keys
21
+ end
22
+
23
+ def get_filtered_data(data)
24
+ filter_params = self._get_filter_params
25
+ unless filter_params.blank?
26
+ return data.where(**filter_params)
27
+ end
28
+
29
+ return data
30
+ end
31
+ end
32
+
33
+ # A filter backend which handles ordering of the recordset.
34
+ class ModelOrderingFilter < BaseFilter
35
+ # Convert ordering string to an ordering configuration.
36
+ def _get_ordering
37
+ return nil unless @controller.class.ordering_query_param
38
+
39
+ order_string = @controller.params[@controller.class.ordering_query_param]
40
+ unless order_string.blank?
41
+ return order_string.split(',').map { |field|
42
+ if field[0] == '-'
43
+ [field[1..-1].to_sym, :desc]
44
+ else
45
+ [field.to_sym, :asc]
46
+ end
47
+ }.to_h
48
+ end
49
+
50
+ return nil
51
+ end
52
+
53
+ def get_filtered_data(data)
54
+ ordering = self._get_ordering
55
+ if ordering && !ordering.empty?
56
+ return data.order(_get_ordering)
57
+ end
58
+ return data
59
+ end
60
+ end
61
+
62
+ # TODO: implement searching within fields rather than exact match filtering (ModelFilter)
63
+ # class ModelSearchFilter < BaseFilter
64
+ # end
65
+ end
@@ -0,0 +1,84 @@
1
+ module RESTFramework
2
+
3
+ # A simple paginator based on page numbers.
4
+ #
5
+ # Example: http://example.com/api/users/?page=3&page_size=50
6
+ class PageNumberPaginator
7
+ def initialize(data:, controller:, **kwargs)
8
+ @data = data
9
+ @controller = controller
10
+ @count = data.count
11
+ @page_size = self._page_size
12
+
13
+ @total_pages = @count / @page_size
14
+ @total_pages += 1 if @count % @page_size
15
+ end
16
+
17
+ def _page_size
18
+ page_size = nil
19
+
20
+ # Get from context, if allowed.
21
+ if @controller.class.page_size_query_param
22
+ page_size = @controller.params[@controller.class.page_size_query_param].presence
23
+ if page_size
24
+ page_size = page_size.to_i
25
+ end
26
+ end
27
+
28
+ # Otherwise, get from config.
29
+ if !page_size && @controller.class.page_size
30
+ page_size = @controller.class.page_size
31
+ end
32
+
33
+ # Fallback to a page size of 15.
34
+ page_size = 15 unless page_size
35
+
36
+ # Ensure we don't exceed the max page size.
37
+ if @controller.class.max_page_size && page_size > @controller.class.max_page_size
38
+ page_size = @controller.class.max_page_size
39
+ end
40
+
41
+ # Ensure we return at least 1.
42
+ return page_size.zero? ? 1 : page_size
43
+ end
44
+
45
+ def _page_query_param
46
+ return @controller.class.page_query_param&.to_sym
47
+ end
48
+
49
+ def get_page(page_number=nil)
50
+ # If page number isn't provided, infer from the params or use 1 as a fallback value.
51
+ if !page_number
52
+ page_number = @controller&.params&.[](self._page_query_param)
53
+ if page_number.blank?
54
+ page_number = 1
55
+ else
56
+ page_number = page_number.to_i
57
+ if page_number.zero?
58
+ page_number = 1
59
+ end
60
+ end
61
+ end
62
+ @page_number = page_number
63
+
64
+ # Get the data page and return it so the caller can serialize the data in the proper format.
65
+ page_index = @page_number - 1
66
+ return @data.limit(@page_size).offset(page_index * @page_size)
67
+ end
68
+
69
+ # Wrap the serialized page with appripriate metadata.
70
+ def get_paginated_response(serialized_page)
71
+ return {
72
+ count: @count,
73
+ page: @page_number,
74
+ total_pages: @total_pages,
75
+ results: serialized_page,
76
+ }
77
+ end
78
+ end
79
+
80
+ # TODO: implement this
81
+ # class CountOffsetPaginator
82
+ # end
83
+
84
+ end
@@ -2,9 +2,8 @@ module RESTFramework
2
2
  class BaseSerializer
3
3
  attr_reader :errors
4
4
 
5
- def initialize(object: nil, data: nil, controller: nil, **kwargs)
5
+ def initialize(object: nil, controller: nil, **kwargs)
6
6
  @object = object
7
- @data = data
8
7
  @controller = controller
9
8
  end
10
9
  end
@@ -12,16 +11,15 @@ module RESTFramework
12
11
  # This serializer uses `.as_json` to serialize objects. Despite the name, `.as_json` is a Rails
13
12
  # method which converts objects to Ruby primitives (with the top-level being either an array or a
14
13
  # hash).
15
- class NativeModelSerializer < BaseSerializer
14
+ class NativeSerializer < BaseSerializer
16
15
  class_attribute :config
17
16
  class_attribute :singular_config
18
17
  class_attribute :plural_config
19
18
  class_attribute :action_config
20
19
 
21
- def initialize(model: nil, many: nil, **kwargs)
20
+ def initialize(many: nil, **kwargs)
22
21
  super(**kwargs)
23
22
  @many = many
24
- @model = model || (@controller ? @controller.send(:get_model) : nil)
25
23
  end
26
24
 
27
25
  # Get controller action, if possible.
@@ -34,41 +32,36 @@ module RESTFramework
34
32
  action = self.get_action
35
33
 
36
34
  if action && self.action_config
37
- # index action should use :list serializer config if :index is not provided
35
+ # Index action should use :list serializer config if :index is not provided.
38
36
  action = :list if action == :index && !self.action_config.key?(:index)
39
37
 
40
38
  return self.action_config[action] if self.action_config[action]
41
39
  end
42
40
 
43
- # no action_config, so try singular/plural config
41
+ # No action_config, so try singular/plural config.
44
42
  return self.plural_config if @many && self.plural_config
45
43
  return self.singular_config if !@many && self.singular_config
46
44
 
47
- # lastly, try the default config
45
+ # Lastly, try returning the default config.
48
46
  return self.config
49
47
  end
50
48
 
51
- # Get a configuration passable to `as_json` for the model.
49
+ # Get a configuration passable to `as_json` for the object.
52
50
  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
-
57
- # return a serializer config if one is defined
58
- serializer_config = @controller.send(:get_native_serializer_config)
59
- return serializer_config if serializer_config
51
+ # Return a locally defined serializer config if one is defined.
52
+ if local_config = self.get_local_serializer_config
53
+ return local_config
54
+ end
60
55
 
61
- # otherwise, build a serializer config from fields
62
- fields = @controller.send(:get_fields) if @controller
63
- unless fields.blank?
64
- columns, methods = fields.partition { |f| f.to_s.in?(@model.column_names) }
65
- return {only: columns, methods: methods}
56
+ # Return a serializer config if one is defined.
57
+ if serializer_config = @controller.send(:get_native_serializer_config)
58
+ return serializer_config
66
59
  end
67
60
 
68
61
  return {}
69
62
  end
70
63
 
71
- # Convert the object(s) to Ruby primitives.
64
+ # Convert the object (record or recordset) to Ruby primitives.
72
65
  def serialize
73
66
  if @object
74
67
  @many = @object.respond_to?(:each) if @many.nil?
@@ -105,4 +98,28 @@ module RESTFramework
105
98
  return @_nested_config[key] = value
106
99
  end
107
100
  end
101
+
102
+ # `NativeModelSerializer` is similar to `NativeSerializer` but with some customizations to work
103
+ # with `ActiveModel`.
104
+ class NativeModelSerializer < NativeSerializer
105
+ def initialize(model: nil, **kwargs)
106
+ super(**kwargs)
107
+ @model = model || (@controller ? @controller.send(:get_model) : nil)
108
+ end
109
+
110
+ # Get a configuration passable to `as_json` for the object.
111
+ def get_serializer_config
112
+ config = super
113
+ return config unless config.blank?
114
+
115
+ # If the config wasn't determined, build a serializer config from model fields.
116
+ fields = @controller.try(:get_fields) if @controller
117
+ unless fields.blank?
118
+ columns, methods = fields.partition { |f| f.to_s.in?(@model.column_names) }
119
+ return {only: columns, methods: methods}
120
+ end
121
+
122
+ return {}
123
+ end
124
+ end
108
125
  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.15
4
+ version: 0.0.16
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-12-09 00:00:00.000000000 Z
11
+ date: 2021-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -43,6 +43,8 @@ files:
43
43
  - lib/rest_framework/controller_mixins/base.rb
44
44
  - lib/rest_framework/controller_mixins/models.rb
45
45
  - lib/rest_framework/engine.rb
46
+ - lib/rest_framework/filters.rb
47
+ - lib/rest_framework/paginators.rb
46
48
  - lib/rest_framework/routers.rb
47
49
  - lib/rest_framework/serializers.rb
48
50
  - lib/rest_framework/version.rb