rest_framework 1.2.0 → 2.0.0.beta2

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.
@@ -111,25 +111,77 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
111
111
  controller_serializer || @controller.class.native_serializer_config
112
112
  end
113
113
 
114
- # Get the associations limit from the controller.
115
- def _associations_limit
116
- return @_associations_limit if defined?(@_associations_limit)
117
-
118
- limit = @controller&.class&.native_serializer_associations_limit
119
-
120
- # Extract the limit from the query parameters if it's set.
121
- if query_param = @controller&.class&.native_serializer_associations_limit_query_param
122
- if @controller.request.query_parameters.key?(query_param)
123
- query_limit = @controller.request.query_parameters[query_param].to_i
124
- if query_limit > 0
125
- limit = query_limit
126
- else
127
- limit = nil
128
- end
129
- end
130
- end
114
+ # The record cap for a collection association (`nil` = unlimited). The default is applied even
115
+ # when the feature is off, so responses are always bounded. `key?` (not `||`) reads the
116
+ # `field_config` override so an explicit `nil` there means unlimited/uncapped rather than falling
117
+ # back to the controller default.
118
+ def _effective_association_limit(association_name, field_config)
119
+ controller = @controller&.class
120
+
121
+ default = field_config.key?(:limit) ?
122
+ field_config[:limit] : controller&.association_limit
123
+ return default unless controller&.enable_association_queries
124
+
125
+ requested = self._requested_association_limit(association_name)
126
+ return default if requested.nil?
127
+
128
+ max = field_config.key?(:limit_max) ?
129
+ field_config[:limit_max] : controller.association_limit_max
130
+
131
+ # `all` means "as many as allowed" — the cap, or unlimited when the cap is `nil`.
132
+ return max if requested == :all
133
+
134
+ max ? [ requested, max ].min : requested
135
+ end
136
+
137
+ # `all`, `none`, and `0` all mean "no limit" — `0` is free to reuse as a sentinel since an
138
+ # association is dropped via `except`, not `limit=0`. Anything else must be a plain positive
139
+ # integer, so a nested/array param or junk can't drive the query.
140
+ def _requested_association_limit(association_name)
141
+ return nil unless prefix = @controller.class.association_query_prefix.presence
142
+
143
+ raw = @controller.request&.query_parameters&.[]("#{prefix}.#{association_name}.limit")
144
+ return nil unless raw.is_a?(String)
145
+
146
+ raw = raw.strip
147
+ return :all if raw.in?(%w[all none])
148
+ return nil unless raw.match?(/\A\d+\z/)
149
+
150
+ # The regex guarantees a non-negative integer, so anything but zero is a positive limit.
151
+ limit = raw.to_i
152
+ limit.zero? ? :all : limit
153
+ end
154
+
155
+ # The fields to serialize for association `f`, honoring a consumer's `?<prefix>.<f>.fields=`
156
+ # request bounded by the allowlist. Only active when the feature is enabled.
157
+ def _effective_association_fields(association_name, ref, field_config)
158
+ default_fields = field_config[:fields]
159
+ return default_fields unless @controller&.class&.enable_association_queries
160
+ return default_fields if ref.polymorphic? # no single target class to bound the request
161
+
162
+ requested = self._requested_association_fields(association_name)
163
+ return default_fields if requested.blank?
164
+
165
+ # The primary key is always kept so records stay identifiable. `_valid_association_field?` is
166
+ # the last line of defense against leaking a non-serializable or nested-association field.
167
+ allowed = (default_fields + (field_config[:requestable_fields] || [])).uniq
168
+ valid = (requested & allowed).select { |sf| self._valid_association_field?(ref, sf) }
169
+ (Array(ref.klass.primary_key).map(&:to_s) + valid).uniq
170
+ end
171
+
172
+ # Only a plain scalar string is honored, so a nested-hash/array param can't reach `where`/`split`.
173
+ def _requested_association_fields(association_name)
174
+ return nil unless prefix = @controller.class.association_query_prefix.presence
175
+
176
+ raw = @controller.request&.query_parameters&.[]("#{prefix}.#{association_name}.fields")
177
+ return nil unless raw.is_a?(String)
178
+
179
+ raw.split(",").map { |x| x.strip.presence }.compact
180
+ end
131
181
 
132
- @_associations_limit = limit
182
+ def _valid_association_field?(ref, field)
183
+ field.in?(ref.klass.column_names) ||
184
+ (ref.klass.method_defined?(field) && !ref.klass.reflect_on_association(field.to_sym))
133
185
  end
134
186
 
135
187
  # Get a serializer configuration from the controller. `@controller` and `@model` must be set.
@@ -158,7 +210,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
158
210
  elsif ref = reflections[f]
159
211
  sub_columns = []
160
212
  sub_methods = []
161
- field_config[:sub_fields].each do |sf|
213
+ self._effective_association_fields(f, ref, field_config).each do |sf|
162
214
  if !ref.polymorphic? && sf.in?(ref.klass.column_names)
163
215
  sub_columns << sf
164
216
  else
@@ -169,9 +221,9 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
169
221
 
170
222
  # Apply certain rules regarding collection associations.
171
223
  if ref.collection?
172
- # If we need to limit the number of serialized association records, then dynamically add a
173
- # serializer method to do so.
174
- if limit = self._associations_limit
224
+ # A finite limit needs a per-record `.limit` query, since eager `includes` can't cap rows
225
+ # per parent; an unlimited (`nil`) association falls through to `includes` preloading.
226
+ if limit = self._effective_association_limit(f, field_config)
175
227
  serializer_methods[f] = f
176
228
  self.define_singleton_method(f) do |record|
177
229
  next record.send(f).limit(limit).as_json(**sub_config)
@@ -181,7 +233,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
181
233
  #
182
234
  # # Even though we use a serializer method, if the count will later be added, then put
183
235
  # # this field into the includes_map.
184
- # if @controller.class.native_serializer_include_associations_count
236
+ # if @controller.class.include_association_count
185
237
  # includes_map[f] = f.to_sym
186
238
  # end
187
239
  else
@@ -190,7 +242,7 @@ class RESTFramework::Serializers::NativeSerializer < RESTFramework::Serializers:
190
242
  end
191
243
 
192
244
  # If we need to include the association count, then add it here.
193
- if @controller.class.native_serializer_include_associations_count
245
+ if @controller.class.include_association_count
194
246
  method_name = "#{f}.count"
195
247
  serializer_methods[method_name] = method_name
196
248
  self.define_singleton_method(method_name) do |record|
@@ -1,59 +1,6 @@
1
1
  module RESTFramework::Utils
2
2
  HTTP_VERB_ORDERING = %w[GET POST PUT PATCH DELETE OPTIONS HEAD]
3
3
 
4
- # Convert `extra_actions` hash to a consistent format: `{path:, methods:, metadata:, kwargs:}`.
5
- def self.parse_extra_actions(extra_actions)
6
- (extra_actions || {}).map { |k, v|
7
- path = k
8
- kwargs = {}
9
-
10
- # Convert structure to path/methods/kwargs.
11
- if v.is_a?(Hash)
12
- # Symbolize keys (which also makes a copy so we don't mutate the original).
13
- v = v.symbolize_keys
14
-
15
- # Cast method/methods to an array.
16
- methods = [ v.delete(:methods), v.delete(:method) ].flatten.compact
17
-
18
- # Override path if it's provided.
19
- if v.key?(:path)
20
- path = v.delete(:path)
21
- end
22
-
23
- # Extract metadata, if provided.
24
- metadata = v.delete(:metadata).presence
25
-
26
- # Pass any further kwargs to the underlying Rails interface.
27
- kwargs = v
28
- else
29
- methods = [ v ].flatten
30
- end
31
-
32
- next [
33
- k,
34
- {
35
- path: path,
36
- methods: methods,
37
- metadata: metadata,
38
- kwargs: kwargs,
39
- }.compact,
40
- ]
41
- }.to_h
42
- end
43
-
44
- def self.get_skipped_builtin_actions(controller_class, singular)
45
- candidates = (
46
- RESTFramework::BUILTIN_ACTIONS.keys - (singular ? [ :index ] : [])
47
- ) + RESTFramework::BUILTIN_MEMBER_ACTIONS.keys
48
-
49
- return candidates unless controller_class.model
50
-
51
- exclude = controller_class.excluded_actions&.to_set || Set.new
52
- candidates.reject do |action|
53
- controller_class.method_defined?(action) && !exclude.include?(action)
54
- end
55
- end
56
-
57
4
  # Get the first route pattern which matches the given request.
58
5
  def self.get_request_route(application_routes, request)
59
6
  # Prefer the route already resolved by the router to avoid an expensive `recognize` call. This
@@ -172,9 +119,8 @@ module RESTFramework::Utils
172
119
  parsed_fields.map(&:to_s)
173
120
  end
174
121
 
175
- # Get the fields for a given model, including not just columns (which includes
176
- # foreign keys), but also associations. Note that we always return an array of
177
- # strings, not symbols.
122
+ # Get the fields for a given model, including not just columns (which includes foreign keys), but
123
+ # also associations. Note that we always return an array of strings, not symbols.
178
124
  def self.fields_for(model, exclude_associations:, action_text:, active_storage:)
179
125
  foreign_keys = model.reflect_on_all_associations(:belongs_to).map(&:foreign_key)
180
126
  base_fields = model.column_names.reject { |c| c.in?(foreign_keys) }
@@ -208,23 +154,23 @@ module RESTFramework::Utils
208
154
  base_fields + associations + atf + asf
209
155
  end
210
156
 
211
- # Get the sub-fields that may be serialized and filtered/ordered for a reflection.
212
- def self.sub_fields_for(ref)
157
+ # Get the association's fields that may be serialized and filtered/ordered for a reflection.
158
+ def self.association_fields_for(ref)
213
159
  if !ref.polymorphic? && model = ref.klass
214
- sub_fields = [ model.primary_key ].flatten.compact
160
+ fields = [ model.primary_key ].flatten.compact
215
161
  label_fields = RESTFramework.config.label_fields
216
162
 
217
163
  # Preferably find a database column to use as label.
218
164
  if match = label_fields.find { |f| f.in?(model.column_names) }
219
- return sub_fields + [ match ]
165
+ return fields + [ match ]
220
166
  end
221
167
 
222
168
  # Otherwise, find a method.
223
169
  if match = label_fields.find { |f| model.method_defined?(f) }
224
- return sub_fields + [ match ]
170
+ return fields + [ match ]
225
171
  end
226
172
 
227
- return sub_fields
173
+ return fields
228
174
  end
229
175
 
230
176
  [ "id", "name" ]
@@ -243,6 +189,30 @@ module RESTFramework::Utils
243
189
  nil
244
190
  end
245
191
 
192
+ # Find the REST controller for `model` at the same namespace level as `current_controller`, e.g.
193
+ # `Api::Demo::MoviesController` + `Genre` => `Api::Demo::GenresController`, or `nil` if none. The
194
+ # `model` match guards against trusting a same-named controller for a different model.
195
+ def self.controller_for_model(current_controller, model)
196
+ return nil unless model && (base_name = current_controller.name)
197
+
198
+ namespace = base_name.deconstantize
199
+ model_name = model.model_name
200
+
201
+ # Plural for a collection controller, singular for a singular-resource one.
202
+ [ model_name.plural, model_name.singular ].each do |name|
203
+ candidate_name = "#{name.camelize}Controller"
204
+ candidate_name = "#{namespace}::#{candidate_name}" if namespace.present?
205
+
206
+ candidate = candidate_name.safe_constantize
207
+ next unless candidate.is_a?(Class) && candidate.include?(RESTFramework::Controller)
208
+ next unless candidate.model == model
209
+
210
+ return candidate
211
+ end
212
+
213
+ nil
214
+ end
215
+
246
216
  # Wrap a serializer with an adapter if it is an ActiveModel::Serializer.
247
217
  def self.wrap_ams(s)
248
218
  if defined?(ActiveModel::Serializer) && (s < ActiveModel::Serializer)
@@ -251,12 +221,4 @@ module RESTFramework::Utils
251
221
 
252
222
  s
253
223
  end
254
-
255
- # Used for deprecated mixins that rely on model being determined from the controller name.
256
- def self.get_model(controller_class)
257
- begin
258
- controller_class.name.demodulize.chomp("Controller").singularize.constantize
259
- rescue NameError
260
- end
261
- end
262
224
  end
@@ -22,11 +22,14 @@ module RESTFramework
22
22
  UNKNOWN
23
23
  end
24
24
 
25
- def self.stamp_version
26
- # Only stamp the version if it's not unknown.
27
- if RESTFramework::VERSION != UNKNOWN
28
- File.write(VERSION_FILEPATH, RESTFramework::VERSION)
25
+ def self.stamp_version(version = nil)
26
+ # Stamp the given version into the VERSION file, deriving it from git when none is provided.
27
+ # Returns the stamped version so callers don't rely on the (require-time) `VERSION` constant.
28
+ version ||= self.get_version
29
+ if version != UNKNOWN
30
+ File.write(VERSION_FILEPATH, version)
29
31
  end
32
+ version
30
33
  end
31
34
 
32
35
  def self.unstamp_version
@@ -34,5 +37,5 @@ module RESTFramework
34
37
  end
35
38
  end
36
39
 
37
- VERSION = Version.get_version
40
+ VERSION = Version.get_version(skip_git: true)
38
41
  end
@@ -1,26 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RESTFramework
4
- BUILTIN_FORM_ACTIONS = [ :new, :edit ].freeze
5
- BUILTIN_ACTIONS = {
6
- index: :get,
7
- new: :get,
8
- create: :post,
9
- }.freeze
10
- BUILTIN_MEMBER_ACTIONS = {
11
- show: :get,
12
- edit: :get,
13
- update: [ :put, :patch ].freeze,
14
- destroy: :delete,
15
- }.freeze
16
- RRF_BUILTIN_ACTIONS = {
17
- options: :options,
18
- }.freeze
19
- RRF_BUILTIN_BULK_ACTIONS = {
20
- update_all: [ :put, :patch ].freeze,
21
- destroy_all: :delete,
22
- }.freeze
23
-
24
4
  # Storage for extra routes and associated metadata.
25
5
  EXTRA_ACTION_ROUTES = Set.new
26
6
  ROUTE_METADATA = {}
@@ -47,6 +27,7 @@ module RESTFramework
47
27
  # Bootstrap Icons
48
28
  "bootstrap-icons.min.css" => {
49
29
  url: "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css",
30
+ sri: "sha384-XGjxtQfXaH2tnPFa9x+ruJTuLE3Aa6LhHSWRr1XeTyhezb4abCG4ccI5AkVDxqC+",
50
31
  inline_fonts: true,
51
32
  },
52
33
 
@@ -74,19 +55,23 @@ module RESTFramework
74
55
  extra_tag_attrs: { class: "rrf-light-mode" },
75
56
  },
76
57
 
77
- # NeatJSON
58
+ # NeatJSON. The package publishes no minified build; jsdelivr's `neatjson.min.js` is synthesized
59
+ # on the fly (so its bytes/SRI aren't stable), so we pin the published `neatjson.js` instead.
78
60
  "neatjson.min.js" => {
79
- url: "https://cdn.jsdelivr.net/npm/neatjson@0.10.6/javascript/neatjson.min.js",
61
+ url: "https://cdn.jsdelivr.net/npm/neatjson@0.10.6/javascript/neatjson.js",
62
+ sri: "sha384-7yRMvyGBuBnnlsgFwUDx7wY7Y/kXt7Irg5xppXVAI0yp3R0870lWaXNP/JE2rbFA",
80
63
  exclude_from_docs: true,
81
64
  },
82
65
 
83
66
  # Trix
84
67
  "trix.min.css" => {
85
68
  url: "https://unpkg.com/trix@2.0.8/dist/trix.css",
69
+ sri: "sha384-Cgg84c/W0Q5VrTzc4ITmV88Ocx4Pn1YlTXPvSTJjX6+lxJRLYrZ4chaighxlqOY1",
86
70
  exclude_from_docs: true,
87
71
  },
88
72
  "trix.min.js" => {
89
73
  url: "https://unpkg.com/trix@2.0.8/dist/trix.umd.min.js",
74
+ sri: "sha384-Ki3zDe3whjAHK/GOksrYLGCU8m0SkmiJQ4Kqm3jQlM3YCl2hFBf17s9bzjVYmXWX",
90
75
  exclude_from_docs: true,
91
76
  },
92
77
  }.map { |name, cfg|
@@ -149,19 +134,6 @@ module RESTFramework
149
134
  # Permits use of `render(api: obj)` syntax over `render_api(obj)`; `true` by default.
150
135
  attr_accessor :register_api_renderer
151
136
 
152
- # Run `rrf_finalize` on controllers automatically using a `TracePoint` hook. This is `true` by
153
- # default, and can be disabled for performance, and must be global because we have to determine
154
- # this before any controller-specific configuration is set. If this is set to `false`, then you
155
- # must manually call `rrf_finalize` after any configuration on each controller that needs to
156
- # participate in:
157
- # - Model delegation, for the helper methods to be defined dynamically.
158
- # - Websockets, for `::Channel` class to be defined dynamically.
159
- # - Controller configuration freezing.
160
- attr_accessor :auto_finalize
161
-
162
- # Freeze configuration attributes during finalization to prevent accidental mutation.
163
- attr_accessor :freeze_config
164
-
165
137
  # Specify reverse association tables that are typically very large, and therefore should not be
166
138
  # added to fields by default.
167
139
  attr_accessor :large_reverse_association_tables
@@ -188,8 +160,6 @@ module RESTFramework
188
160
 
189
161
  def initialize
190
162
  self.register_api_renderer = true
191
- self.auto_finalize = true
192
- self.freeze_config = true
193
163
 
194
164
  self.show_backtrace = Rails.env.development?
195
165
 
@@ -221,7 +191,6 @@ end
221
191
  require_relative "rest_framework/engine"
222
192
  require_relative "rest_framework/errors"
223
193
  require_relative "rest_framework/filters"
224
- require_relative "rest_framework/mixins"
225
194
  require_relative "rest_framework/paginators"
226
195
  require_relative "rest_framework/routers"
227
196
  require_relative "rest_framework/serializers"
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: 1.2.0
4
+ version: 2.0.0.beta2
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: 2026-04-22 00:00:00.000000000 Z
11
+ date: 2026-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -55,6 +55,7 @@ files:
55
55
  - app/views/rest_framework/routes_and_forms/routes/_route.html.erb
56
56
  - lib/rest_framework.rb
57
57
  - lib/rest_framework/controller.rb
58
+ - lib/rest_framework/controller/actions.rb
58
59
  - lib/rest_framework/controller/bulk.rb
59
60
  - lib/rest_framework/controller/crud.rb
60
61
  - lib/rest_framework/controller/openapi.rb
@@ -66,10 +67,6 @@ files:
66
67
  - lib/rest_framework/filters/query_filter.rb
67
68
  - lib/rest_framework/filters/ransack_filter.rb
68
69
  - lib/rest_framework/filters/search_filter.rb
69
- - lib/rest_framework/mixins.rb
70
- - lib/rest_framework/mixins/base_controller_mixin.rb
71
- - lib/rest_framework/mixins/bulk_model_controller_mixin.rb
72
- - lib/rest_framework/mixins/model_controller_mixin.rb
73
70
  - lib/rest_framework/paginators.rb
74
71
  - lib/rest_framework/paginators/base_paginator.rb
75
72
  - lib/rest_framework/paginators/page_number_paginator.rb
@@ -101,9 +98,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
101
98
  version: 2.7.5
102
99
  required_rubygems_version: !ruby/object:Gem::Requirement
103
100
  requirements:
104
- - - ">="
101
+ - - ">"
105
102
  - !ruby/object:Gem::Version
106
- version: '0'
103
+ version: 1.3.1
107
104
  requirements: []
108
105
  rubygems_version: 3.4.10
109
106
  signing_key:
@@ -1,12 +0,0 @@
1
- module RESTFramework::Mixins::BaseControllerMixin
2
- def self.included(base)
3
- RESTFramework.deprecator.warn(
4
- "BaseControllerMixin is deprecated; use RESTFramework::Controller instead.",
5
- )
6
-
7
- base.include(RESTFramework::Controller)
8
- end
9
- end
10
-
11
- # Alias for convenience.
12
- RESTFramework::BaseControllerMixin = RESTFramework::Mixins::BaseControllerMixin
@@ -1,55 +0,0 @@
1
- module RESTFramework::Mixins::BulkCreateModelMixin
2
- def self.included(base)
3
- RESTFramework.deprecator.warn(<<~TXT).squish
4
- BulkCreateModelMixin is deprecated; set the `bulk = true` class attribute instead.
5
- TXT
6
-
7
- base.bulk = true
8
- end
9
- end
10
-
11
- # Mixin for updating records in bulk.
12
- module RESTFramework::Mixins::BulkUpdateModelMixin
13
- def self.included(base)
14
- RESTFramework.deprecator.warn(<<~TXT).squish
15
- BulkUpdateModelMixin is deprecated; set the `bulk = true`, and `excluded_actions` class
16
- attributes instead.
17
- TXT
18
-
19
- base.bulk = true
20
- base.excluded_actions = (base.excluded_actions - [ :update_all ]).freeze
21
- end
22
- end
23
-
24
- # Mixin for destroying records in bulk.
25
- module RESTFramework::Mixins::BulkDestroyModelMixin
26
- def self.included(base)
27
- RESTFramework.deprecator.warn(<<~TXT).squish
28
- BulkDestroyModelMixin is deprecated; set the `bulk = true`, and `excluded_actions` class
29
- attributes instead.
30
- TXT
31
-
32
- base.bulk = true
33
- base.excluded_actions = (base.excluded_actions - [ :destroy_all ]).freeze
34
- end
35
- end
36
-
37
- # Mixin that includes all the CRUD bulk mixins.
38
- module RESTFramework::Mixins::BulkModelControllerMixin
39
- def self.included(base)
40
- RESTFramework.deprecator.warn(<<~TXT).squish
41
- BulkModelControllerMixin is deprecated; use RESTFramework::Controller and set the `model` and
42
- `bulk = true` class attributes instead.
43
- TXT
44
-
45
- base.include(RESTFramework::Controller)
46
- base.model = RESTFramework::Utils.get_model(base)
47
- base.bulk = true
48
- end
49
- end
50
-
51
- # Aliases for convenience.
52
- RESTFramework::BulkCreateModelMixin = RESTFramework::Mixins::BulkCreateModelMixin
53
- RESTFramework::BulkUpdateModelMixin = RESTFramework::Mixins::BulkUpdateModelMixin
54
- RESTFramework::BulkDestroyModelMixin = RESTFramework::Mixins::BulkDestroyModelMixin
55
- RESTFramework::BulkModelControllerMixin = RESTFramework::Mixins::BulkModelControllerMixin
@@ -1,110 +0,0 @@
1
- module RESTFramework::Mixins::BaseModelControllerMixin
2
- def self.included(base)
3
- RESTFramework.deprecator.warn(<<~TXT).squish
4
- BaseModelControllerMixin is deprecated; use RESTFramework::Controller and set the `model` and
5
- `excluded_actions` class attributes instead.
6
- TXT
7
-
8
- base.include(RESTFramework::Controller)
9
- base.model = RESTFramework::Utils.get_model(base)
10
- base.excluded_actions = [
11
- :index, :show, :create, :update, :destroy, :update_all, :destroy_all
12
- ].freeze
13
- end
14
- end
15
-
16
- module RESTFramework::Mixins::ListModelMixin
17
- def self.included(base)
18
- RESTFramework.deprecator.warn(
19
- "ListModelMixin is deprecated; set the `excluded_actions` class attribute instead.",
20
- )
21
-
22
- if base.excluded_actions
23
- base.excluded_actions = (base.excluded_actions - [ :index ]).freeze
24
- end
25
- end
26
- end
27
-
28
- module RESTFramework::Mixins::ShowModelMixin
29
- def self.included(base)
30
- RESTFramework.deprecator.warn(
31
- "ShowModelMixin is deprecated; set the `excluded_actions` class attribute instead.",
32
- )
33
-
34
- if base.excluded_actions
35
- base.excluded_actions = (base.excluded_actions - [ :show ]).freeze
36
- end
37
- end
38
- end
39
-
40
- module RESTFramework::Mixins::CreateModelMixin
41
- def self.included(base)
42
- RESTFramework.deprecator.warn(
43
- "CreateModelMixin is deprecated; set the `excluded_actions` class attribute instead.",
44
- )
45
-
46
- if base.excluded_actions
47
- base.excluded_actions = (base.excluded_actions - [ :create ]).freeze
48
- end
49
- end
50
- end
51
-
52
- module RESTFramework::Mixins::UpdateModelMixin
53
- def self.included(base)
54
- RESTFramework.deprecator.warn(
55
- "UpdateModelMixin is deprecated; set the `excluded_actions` class attribute instead.",
56
- )
57
-
58
- if base.excluded_actions
59
- base.excluded_actions = (base.excluded_actions - [ :update ]).freeze
60
- end
61
- end
62
- end
63
-
64
- module RESTFramework::Mixins::DestroyModelMixin
65
- def self.included(base)
66
- RESTFramework.deprecator.warn(
67
- "DestroyModelMixin is deprecated; set the `excluded_actions` class attribute instead.",
68
- )
69
-
70
- if base.excluded_actions
71
- base.excluded_actions = (base.excluded_actions - [ :destroy ]).freeze
72
- end
73
- end
74
- end
75
-
76
- module RESTFramework::Mixins::ReadOnlyModelControllerMixin
77
- def self.included(base)
78
- RESTFramework.deprecator.warn(<<~TXT).squish
79
- ReadOnlyModelControllerMixin is deprecated; use RESTFramework::Controller and set the `model`
80
- and `excluded_actions` class attributes instead.
81
- TXT
82
-
83
- base.include(RESTFramework::Controller)
84
- base.model = RESTFramework::Utils.get_model(base)
85
- base.excluded_actions = [ :create, :update, :destroy, :update_all, :destroy_all ].freeze
86
- end
87
- end
88
-
89
- module RESTFramework::Mixins::ModelControllerMixin
90
- def self.included(base)
91
- RESTFramework.deprecator.warn(<<~TXT).squish
92
- ModelControllerMixin is deprecated; use RESTFramework::Controller and set the `model` class
93
- attribute instead.
94
- TXT
95
-
96
- base.include(RESTFramework::Controller)
97
- base.model = RESTFramework::Utils.get_model(base)
98
- base.excluded_actions = nil
99
- end
100
- end
101
-
102
- # Aliases for convenience.
103
- RESTFramework::BaseModelControllerMixin = RESTFramework::Mixins::BaseModelControllerMixin
104
- RESTFramework::ListModelMixin = RESTFramework::Mixins::ListModelMixin
105
- RESTFramework::ShowModelMixin = RESTFramework::Mixins::ShowModelMixin
106
- RESTFramework::CreateModelMixin = RESTFramework::Mixins::CreateModelMixin
107
- RESTFramework::UpdateModelMixin = RESTFramework::Mixins::UpdateModelMixin
108
- RESTFramework::DestroyModelMixin = RESTFramework::Mixins::DestroyModelMixin
109
- RESTFramework::ReadOnlyModelControllerMixin = RESTFramework::Mixins::ReadOnlyModelControllerMixin
110
- RESTFramework::ModelControllerMixin = RESTFramework::Mixins::ModelControllerMixin
@@ -1,7 +0,0 @@
1
- module RESTFramework::Mixins
2
- end
3
-
4
- require_relative "mixins/base_controller_mixin"
5
-
6
- require_relative "mixins/bulk_model_controller_mixin"
7
- require_relative "mixins/model_controller_mixin"