rest_framework 0.6.13 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fcc66a1bc2a8c965fcaf04106db51a08c98623a642803634fc96d5eccce9283f
4
- data.tar.gz: 06c49e1eb116813833c01810379a7f377023bb37a0bb57429c254224f8b260d9
3
+ metadata.gz: bcc4c1783a1d0dc42b862d9daf32c6d9ef2ae029483f61ac7c2e971c6c0558db
4
+ data.tar.gz: '091682390838dd5f5c5db8ea2e216f336863f06b77488c88dbc68b5c59b68e22'
5
5
  SHA512:
6
- metadata.gz: 6398f494b9c920a0e9765733c6be871d0cdee94fc12a2863fa7bf0bfc1bba41f601713a53b61ba3d57fcd1b3b45001eadbe6ac26b77b4bd69595ad1ae84e2f06
7
- data.tar.gz: 2610d28a5d5b98fd6be70105d04a292d2acb4c3efc9d5ece74ba1a00b90e4968a55ccefc824773c2609015298221c5315ea929440e29923bba9500ce495c8c78
6
+ metadata.gz: 441f74ad60ade750e7483364b9e5a73fb58cb9452dc8a5e11988e154758fba345391b44bf87143a6c3e1f9ff1ec6fb773c51af30990776fedeac7c5d96461676
7
+ data.tar.gz: 0acb74c34c862ba9fd74e9b76ea4c1b9b413aac4989250aab3ee0b6a1cf0a1643f8095ad552d4f8e2c53cc2b2bbdf60c4efbd87d8a48605cab6d051c0082da2d
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.13
1
+ 0.7.0
@@ -57,6 +57,9 @@
57
57
  <% end %>
58
58
  <button type="button" class="btn btn-primary" onclick="rrfRefresh(this)">GET</button>
59
59
  </div>
60
+ <% if @description.present? %>
61
+ <br><br><p style="display: inline-block; margin-bottom: 0"><%= @description %></p>
62
+ <% end %>
60
63
  </div>
61
64
  </div>
62
65
  <hr/>
@@ -6,12 +6,59 @@ require_relative "../utils"
6
6
  # the ability to route arbitrary actions with `extra_actions`. This is also where `api_response`
7
7
  # is defined.
8
8
  module RESTFramework::BaseControllerMixin
9
+ RRF_BASE_CONTROLLER_CONFIG = {
10
+ filter_pk_from_request_body: true,
11
+ exclude_body_fields: [:created_at, :created_by, :updated_at, :updated_by],
12
+ accept_generic_params_as_body_params: false,
13
+ show_backtrace: false,
14
+ extra_actions: nil,
15
+ extra_member_actions: nil,
16
+ filter_backends: nil,
17
+ singleton_controller: nil,
18
+
19
+ # Metadata and display options.
20
+ title: nil,
21
+ description: nil,
22
+ inflect_acronyms: ["ID", "REST", "API"],
23
+
24
+ # Options related to serialization.
25
+ rescue_unknown_format_with: :json,
26
+ serializer_class: nil,
27
+ serialize_to_json: true,
28
+ serialize_to_xml: true,
29
+
30
+ # Options related to pagination.
31
+ paginator_class: nil,
32
+ page_size: 20,
33
+ page_query_param: "page",
34
+ page_size_query_param: "page_size",
35
+ max_page_size: nil,
36
+
37
+ # Option to disable serializer adapters by default, mainly introduced because Active Model
38
+ # Serializers will do things like serialize `[]` into `{"":[]}`.
39
+ disable_adapters_by_default: true,
40
+ }
41
+
9
42
  # Default action for API root.
10
43
  def root
11
- api_response({message: "This is the root of your awesome API!"})
44
+ api_response({message: "This is the API root."})
12
45
  end
13
46
 
14
47
  module ClassMethods
48
+ # Get the title of this controller. By default, this is the name of the controller class,
49
+ # titleized and with any custom inflection acronyms applied.
50
+ def get_title
51
+ return self.title || RESTFramework::Utils.inflect(
52
+ self.name.demodulize.chomp("Controller").titleize(keep_id_suffix: true),
53
+ self.inflect_acronyms,
54
+ )
55
+ end
56
+
57
+ # Get a label from a field/column name, titleized and inflected.
58
+ def get_label(s)
59
+ return RESTFramework::Utils.inflect(s.titleize(keep_id_suffix: true), self.inflect_acronyms)
60
+ end
61
+
15
62
  # Collect actions (including extra actions) metadata for this controller.
16
63
  def get_actions_metadata
17
64
  actions = {}
@@ -20,12 +67,14 @@ module RESTFramework::BaseControllerMixin
20
67
  RESTFramework::BUILTIN_ACTIONS.merge(
21
68
  RESTFramework::RRF_BUILTIN_ACTIONS,
22
69
  ).each do |action, methods|
23
- actions[action] = {path: "", methods: methods} if self.method_defined?(action)
70
+ if self.method_defined?(action)
71
+ actions[action] = {path: "", methods: methods, type: :builtin}
72
+ end
24
73
  end
25
74
 
26
75
  # Add extra actions.
27
76
  if extra_actions = self.try(:extra_actions)
28
- actions.merge!(RESTFramework::Utils.parse_extra_actions(extra_actions))
77
+ actions.merge!(RESTFramework::Utils.parse_extra_actions(extra_actions, controller: self))
29
78
  end
30
79
 
31
80
  return actions
@@ -37,12 +86,14 @@ module RESTFramework::BaseControllerMixin
37
86
 
38
87
  # Start with builtin actions.
39
88
  RESTFramework::BUILTIN_MEMBER_ACTIONS.each do |action, methods|
40
- actions[action] = {path: "", methods: methods} if self.method_defined?(action)
89
+ if self.method_defined?(action)
90
+ actions[action] = {path: "", methods: methods, type: :builtin}
91
+ end
41
92
  end
42
93
 
43
94
  # Add extra actions.
44
95
  if extra_actions = self.try(:extra_member_actions)
45
- actions.merge!(RESTFramework::Utils.parse_extra_actions(extra_actions))
96
+ actions.merge!(RESTFramework::Utils.parse_extra_actions(extra_actions, controller: self))
46
97
  end
47
98
 
48
99
  return actions
@@ -51,8 +102,8 @@ module RESTFramework::BaseControllerMixin
51
102
  # Get a hash of metadata to be rendered in the `OPTIONS` response. Cache the result.
52
103
  def get_options_metadata
53
104
  return @_base_options_metadata ||= {
54
- name: self.metadata&.name || self.controller_name.titleize,
55
- description: self.metadata&.description,
105
+ title: self.get_title,
106
+ description: self.description,
56
107
  renders: [
57
108
  "text/html",
58
109
  self.serialize_to_json ? "application/json" : nil,
@@ -62,6 +113,16 @@ module RESTFramework::BaseControllerMixin
62
113
  member_actions: self.get_member_actions_metadata,
63
114
  }.compact
64
115
  end
116
+
117
+ # Define any behavior to execute at the end of controller definition.
118
+ def rrf_finalize
119
+ if RESTFramework.config.freeze_config
120
+ self::RRF_BASE_CONTROLLER_CONFIG.keys.each { |k|
121
+ v = self.send(k)
122
+ v.freeze if v.is_a?(Hash) || v.is_a?(Array)
123
+ }
124
+ end
125
+ end
65
126
  end
66
127
 
67
128
  def self.included(base)
@@ -70,34 +131,7 @@ module RESTFramework::BaseControllerMixin
70
131
  base.extend(ClassMethods)
71
132
 
72
133
  # Add class attributes (with defaults) unless they already exist.
73
- {
74
- filter_pk_from_request_body: true,
75
- exclude_body_fields: [:created_at, :created_by, :updated_at, :updated_by],
76
- accept_generic_params_as_body_params: false,
77
- show_backtrace: false,
78
- extra_actions: nil,
79
- extra_member_actions: nil,
80
- filter_backends: nil,
81
- singleton_controller: nil,
82
- metadata: nil,
83
-
84
- # Options related to serialization.
85
- rescue_unknown_format_with: :json,
86
- serializer_class: nil,
87
- serialize_to_json: true,
88
- serialize_to_xml: true,
89
-
90
- # Options related to pagination.
91
- paginator_class: nil,
92
- page_size: 20,
93
- page_query_param: "page",
94
- page_size_query_param: "page_size",
95
- max_page_size: nil,
96
-
97
- # Option to disable serializer adapters by default, mainly introduced because Active Model
98
- # Serializers will do things like serialize `[]` into `{"":[]}`.
99
- disable_adapters_by_default: true,
100
- }.each do |a, default|
134
+ RRF_BASE_CONTROLLER_CONFIG.each do |a, default|
101
135
  next if base.respond_to?(a)
102
136
 
103
137
  base.class_attribute(a)
@@ -126,6 +160,19 @@ module RESTFramework::BaseControllerMixin
126
160
  base.rescue_from(ActiveRecord::RecordNotSaved, with: :record_not_saved)
127
161
  base.rescue_from(ActiveRecord::RecordNotDestroyed, with: :record_not_destroyed)
128
162
  base.rescue_from(ActiveModel::UnknownAttributeError, with: :unknown_attribute_error)
163
+
164
+ # Use `TracePoint` hook to automatically call `rrf_finalize`.
165
+ unless RESTFramework.config.disable_auto_finalize
166
+ TracePoint.trace(:end) do |t|
167
+ next if base != t.self
168
+
169
+ base.rrf_finalize
170
+
171
+ # It's important to disable the trace once we've found the end of the base class definition,
172
+ # for performance.
173
+ t.disable
174
+ end
175
+ end
129
176
  end
130
177
 
131
178
  # Get the configured serializer class.
@@ -269,7 +316,8 @@ module RESTFramework::BaseControllerMixin
269
316
  @xml_payload = payload.to_xml if self.class.serialize_to_xml
270
317
  end
271
318
  @template_logo_text ||= "Rails REST Framework"
272
- @title ||= self.controller_name.titleize
319
+ @title ||= self.class.get_title
320
+ @description ||= self.class.description
273
321
  @route_props, @route_groups = RESTFramework::Utils.get_routes(
274
322
  Rails.application.routes, request
275
323
  )
@@ -5,6 +5,44 @@ require_relative "../filters"
5
5
  module RESTFramework::BaseModelControllerMixin
6
6
  include RESTFramework::BaseControllerMixin
7
7
 
8
+ RRF_BASE_MODEL_CONTROLLER_CONFIG = {
9
+ # Core attributes related to models.
10
+ model: nil,
11
+ recordset: nil,
12
+
13
+ # Attributes for configuring record fields.
14
+ fields: nil,
15
+ action_fields: nil,
16
+
17
+ # Attributes for finding records.
18
+ find_by_fields: nil,
19
+ find_by_query_param: "find_by",
20
+
21
+ # Attributes for create/update parameters.
22
+ allowed_parameters: nil,
23
+ allowed_action_parameters: nil,
24
+
25
+ # Attributes for the default native serializer.
26
+ native_serializer_config: nil,
27
+ native_serializer_singular_config: nil,
28
+ native_serializer_plural_config: nil,
29
+ native_serializer_only_query_param: "only",
30
+ native_serializer_except_query_param: "except",
31
+
32
+ # Attributes for default model filtering, ordering, and searching.
33
+ filterset_fields: nil,
34
+ ordering_fields: nil,
35
+ ordering_query_param: "ordering",
36
+ ordering_no_reorder: false,
37
+ search_fields: nil,
38
+ search_query_param: "search",
39
+ search_ilike: false,
40
+
41
+ # Other misc attributes.
42
+ create_from_recordset: true, # Option for `recordset.create` vs `Model.create` behavior.
43
+ filter_recordset_before_find: true, # Control if filtering is done before find.
44
+ }
45
+
8
46
  module ClassMethods
9
47
  IGNORE_VALIDATORS_WITH_KEYS = [:if, :unless]
10
48
 
@@ -19,8 +57,8 @@ module RESTFramework::BaseModelControllerMixin
19
57
  rescue NameError
20
58
  end
21
59
 
22
- # Delegate to the recordset's model, if it's defined.
23
- unless from_get_recordset # Prevent infinite recursion.
60
+ # Delegate to the recordset's model, if it's defined. This option prevents infinite recursion.
61
+ unless from_get_recordset
24
62
  # Instantiate a new controller to get the recordset.
25
63
  controller = self.new
26
64
  controller.request = ActionController::TestRequest.new
@@ -34,24 +72,34 @@ module RESTFramework::BaseModelControllerMixin
34
72
  return nil
35
73
  end
36
74
 
75
+ # Override `get_label` to include ActiveRecord i18n-translated column names.
76
+ def get_label(s)
77
+ return self.get_model.human_attribute_name(s, default: super)
78
+ end
79
+
37
80
  # Get metadata about the resource's fields.
38
81
  def get_fields_metadata(fields: nil)
39
82
  # Get metadata sources.
40
83
  model = self.get_model
41
- fields ||= self.fields || model&.column_names || []
84
+ fields ||= self.fields || model.column_names || []
42
85
  fields = fields.map(&:to_s)
43
- columns = model&.columns_hash
44
- column_defaults = model&.column_defaults
45
- attributes = model&._default_attributes
86
+ columns = model.columns_hash
87
+ column_defaults = model.column_defaults
88
+ attributes = model._default_attributes
46
89
 
47
90
  return fields.map { |f|
48
91
  # Initialize metadata to make the order consistent.
49
92
  metadata = {
50
- type: nil, kind: nil, label: nil, primary_key: nil, required: nil, read_only: nil
93
+ type: nil,
94
+ kind: nil,
95
+ label: self.get_label(f),
96
+ primary_key: nil,
97
+ required: nil,
98
+ read_only: nil,
51
99
  }
52
100
 
53
101
  # Determine `primary_key` based on model.
54
- if model&.primary_key == f
102
+ if model.primary_key == f
55
103
  metadata[:primary_key] = true
56
104
  end
57
105
 
@@ -59,7 +107,6 @@ module RESTFramework::BaseModelControllerMixin
59
107
  if column = columns[f]
60
108
  metadata[:type] = column.type
61
109
  metadata[:required] = true unless column.null
62
- metadata[:label] = column.human_name.instance_eval { |n| n == "Id" ? "ID" : n }
63
110
  metadata[:kind] = "column"
64
111
  end
65
112
 
@@ -121,73 +168,15 @@ module RESTFramework::BaseModelControllerMixin
121
168
  },
122
169
  )
123
170
  end
124
- end
125
-
126
- def self.included(base)
127
- return unless base.is_a?(Class)
128
-
129
- RESTFramework::BaseControllerMixin.included(base)
130
- base.extend(ClassMethods)
131
-
132
- # Add class attributes (with defaults) unless they already exist.
133
- {
134
- # Core attributes related to models.
135
- model: nil,
136
- recordset: nil,
137
-
138
- # Attributes for configuring record fields.
139
- fields: nil,
140
- action_fields: nil,
141
- metadata_fields: nil,
142
-
143
- # Attributes for finding records.
144
- find_by_fields: nil,
145
- find_by_query_param: "find_by",
146
-
147
- # Attributes for create/update parameters.
148
- allowed_parameters: nil,
149
- allowed_action_parameters: nil,
150
-
151
- # Attributes for the default native serializer.
152
- native_serializer_config: nil,
153
- native_serializer_singular_config: nil,
154
- native_serializer_plural_config: nil,
155
- native_serializer_only_query_param: "only",
156
- native_serializer_except_query_param: "except",
157
-
158
- # Attributes for default model filtering, ordering, and searching.
159
- filterset_fields: nil,
160
- ordering_fields: nil,
161
- ordering_query_param: "ordering",
162
- ordering_no_reorder: false,
163
- search_fields: nil,
164
- search_query_param: "search",
165
- search_ilike: false,
166
-
167
- # Other misc attributes.
168
- create_from_recordset: true, # Option for `recordset.create` vs `Model.create` behavior.
169
- filter_recordset_before_find: true, # Control if filtering is done before find.
170
- }.each do |a, default|
171
- next if base.respond_to?(a)
172
-
173
- base.class_attribute(a)
174
-
175
- # Set default manually so we can still support Rails 4. Maybe later we can use the default
176
- # parameter on `class_attribute`.
177
- base.send(:"#{a}=", default)
178
- end
179
-
180
- # Actions to run at the end of the class definition.
181
- TracePoint.trace(:end) do |t|
182
- next if base != t.self
183
171
 
172
+ def setup_delegation
184
173
  # Delegate extra actions.
185
- base.extra_actions&.each do |action, config|
174
+ self.extra_actions&.each do |action, config|
186
175
  next unless config.is_a?(Hash) && config[:delegate]
176
+ next unless self.get_model.respond_to?(action)
187
177
 
188
- base.define_method(action) do
178
+ self.define_method(action) do
189
179
  model = self.class.get_model
190
- next unless model.respond_to?(action)
191
180
 
192
181
  if model.method(action).parameters.last&.first == :keyrest
193
182
  return api_response(model.send(action, **params))
@@ -198,12 +187,12 @@ module RESTFramework::BaseModelControllerMixin
198
187
  end
199
188
 
200
189
  # Delegate extra member actions.
201
- base.extra_member_actions&.each do |action, config|
190
+ self.extra_member_actions&.each do |action, config|
202
191
  next unless config.is_a?(Hash) && config[:delegate]
192
+ next unless self.get_model.method_defined?(action)
203
193
 
204
- base.define_method(action) do
194
+ self.define_method(action) do
205
195
  record = self.get_record
206
- next unless record.respond_to?(action)
207
196
 
208
197
  if record.method(action).parameters.last&.first == :keyrest
209
198
  return api_response(record.send(action, **params))
@@ -212,10 +201,38 @@ module RESTFramework::BaseModelControllerMixin
212
201
  end
213
202
  end
214
203
  end
204
+ end
205
+
206
+ # Define any behavior to execute at the end of controller definition.
207
+ def rrf_finalize
208
+ super
209
+ self.setup_delegation
210
+ # self.setup_channel
215
211
 
216
- # It's important to disable the trace once we've found the end of the base class definition,
217
- # for performance.
218
- t.disable
212
+ if RESTFramework.config.freeze_config
213
+ self::RRF_BASE_MODEL_CONTROLLER_CONFIG.keys.each { |k|
214
+ v = self.send(k)
215
+ v.freeze if v.is_a?(Hash) || v.is_a?(Array)
216
+ }
217
+ end
218
+ end
219
+ end
220
+
221
+ def self.included(base)
222
+ return unless base.is_a?(Class)
223
+
224
+ RESTFramework::BaseControllerMixin.included(base)
225
+ base.extend(ClassMethods)
226
+
227
+ # Add class attributes (with defaults) unless they already exist.
228
+ RRF_BASE_MODEL_CONTROLLER_CONFIG.each do |a, default|
229
+ next if base.respond_to?(a)
230
+
231
+ base.class_attribute(a)
232
+
233
+ # Set default manually so we can still support Rails 4. Maybe later we can use the default
234
+ # parameter on `class_attribute`.
235
+ base.send(:"#{a}=", default)
219
236
  end
220
237
  end
221
238
 
@@ -39,8 +39,10 @@ module ActionDispatch::Routing
39
39
 
40
40
  # Interal interface for routing extra actions.
41
41
  def _route_extra_actions(actions, &block)
42
- actions.each do |action, config|
43
- config[:methods].each do |m|
42
+ parsed_actions = RESTFramework::Utils.parse_extra_actions(actions)
43
+
44
+ parsed_actions.each do |action, config|
45
+ [config[:methods]].flatten.each do |m|
44
46
  public_send(m, config[:path], action: action, **(config[:kwargs] || {}))
45
47
  end
46
48
  yield if block_given?
@@ -84,17 +86,13 @@ module ActionDispatch::Routing
84
86
  public_send(resource_method, name, except: skip, **kwargs) do
85
87
  if controller_class.respond_to?(:extra_member_actions)
86
88
  member do
87
- self._route_extra_actions(
88
- RESTFramework::Utils.parse_extra_actions(controller_class.extra_member_actions),
89
- )
89
+ self._route_extra_actions(controller_class.extra_member_actions)
90
90
  end
91
91
  end
92
92
 
93
93
  collection do
94
94
  # Route extra controller-defined actions.
95
- self._route_extra_actions(
96
- RESTFramework::Utils.parse_extra_actions(controller_class.extra_actions),
97
- )
95
+ self._route_extra_actions(controller_class.extra_actions)
98
96
 
99
97
  # Route extra RRF-defined actions.
100
98
  RESTFramework::RRF_BUILTIN_ACTIONS.each do |action, methods|
@@ -155,9 +153,7 @@ module ActionDispatch::Routing
155
153
 
156
154
  collection do
157
155
  # Route extra controller-defined actions.
158
- self._route_extra_actions(
159
- RESTFramework::Utils.parse_extra_actions(controller_class.extra_actions),
160
- )
156
+ self._route_extra_actions(controller_class.extra_actions)
161
157
 
162
158
  # Route extra RRF-defined actions.
163
159
  RESTFramework::RRF_BUILTIN_ACTIONS.each do |action, methods|
@@ -1,20 +1,30 @@
1
1
  module RESTFramework::Utils
2
2
  HTTP_METHOD_ORDERING = %w(GET POST PUT PATCH DELETE OPTIONS HEAD)
3
3
 
4
- # Convert `extra_actions` hash to a consistent format: `{path:, methods:, kwargs:}`.
5
- def self.parse_extra_actions(extra_actions)
4
+ # Convert `extra_actions` hash to a consistent format: `{path:, methods:, kwargs:}`, and
5
+ # additional metadata fields.
6
+ #
7
+ # If a controller is provided, labels will be added to any metadata fields.
8
+ def self.parse_extra_actions(extra_actions, controller: nil)
6
9
  return (extra_actions || {}).map { |k, v|
7
10
  path = k
8
11
 
9
12
  # Convert structure to path/methods/kwargs.
10
13
  if v.is_a?(Hash) # Allow kwargs to be used to define path differently from the key.
14
+ # Symbolize keys (which also makes a copy so we don't mutate the original).
11
15
  v = v.symbolize_keys
16
+ methods = v.delete(:methods)
12
17
 
13
- # Ensure methods is an array.
14
- if v[:methods].is_a?(String) || v[:methods].is_a?(Symbol)
15
- methods = [v.delete(:methods)]
16
- else
17
- methods = v.delete(:methods)
18
+ # First, remove any metadata keys.
19
+ delegate = v.delete(:delegate)
20
+ fields = v.delete(:fields)
21
+
22
+ # Add label to fields.
23
+ if controller && fields
24
+ fields = fields.map { |f| [f, {}] }.to_h if f.is_a?(Array)
25
+ fields&.each do |field, cfg|
26
+ cfg[:label] = controller.get_label(field)
27
+ end
18
28
  end
19
29
 
20
30
  # Override path if it's provided.
@@ -23,14 +33,24 @@ module RESTFramework::Utils
23
33
  end
24
34
 
25
35
  # Pass any further kwargs to the underlying Rails interface.
26
- kwargs = v.presence&.except(:delegate)
27
- elsif v.is_a?(Symbol) || v.is_a?(String)
28
- methods = [v]
36
+ kwargs = v.presence
37
+ elsif v.is_a?(Array) && v.length == 1
38
+ methods = v[0]
29
39
  else
30
40
  methods = v
31
41
  end
32
42
 
33
- [k, {path: path, methods: methods, kwargs: kwargs}.compact]
43
+ next [
44
+ k,
45
+ {
46
+ path: path,
47
+ methods: methods,
48
+ kwargs: kwargs,
49
+ delegate: delegate,
50
+ fields: fields,
51
+ type: :extra,
52
+ }.compact,
53
+ ]
34
54
  }.to_h
35
55
  end
36
56
 
@@ -108,4 +128,13 @@ module RESTFramework::Utils
108
128
  [request.params[:controller] == c ? 0 : 1, c.count("/"), c]
109
129
  }.to_h
110
130
  end
131
+
132
+ # Custom inflector for RESTful controllers.
133
+ def self.inflect(s, acronyms=nil)
134
+ acronyms&.each do |acronym|
135
+ s = s.gsub(/\b#{acronym}\b/i, acronym)
136
+ end
137
+
138
+ return s
139
+ end
111
140
  end
@@ -13,6 +13,31 @@ module RESTFramework
13
13
  RRF_BUILTIN_ACTIONS = {
14
14
  options: :options,
15
15
  }.freeze
16
+
17
+ # Global configuration should be kept minimal, as controller-level configurations allows multiple
18
+ # APIs to be defined to behave differently.
19
+ class Config
20
+ # Do not run `rrf_finalize` on controllers automatically using a `TracePoint` hook. This is a
21
+ # performance option and must be global because we have to determine this before any
22
+ # controller-specific configuration is set. If this is set to `true`, then you must manually
23
+ # call `rrf_finalize` after any configuration on each controller that needs to participate
24
+ # in:
25
+ # - Model delegation, for the helper methods to be defined dynamically.
26
+ # - Websockets, for `::Channel` class to be defined dynamically.
27
+ # - Controller configuration finalizatino.
28
+ attr_accessor :disable_auto_finalize
29
+
30
+ # Freeze configuration attributes during finalization to prevent accidental mutation.
31
+ attr_accessor :freeze_config
32
+ end
33
+
34
+ def self.config
35
+ return @config ||= Config.new
36
+ end
37
+
38
+ def self.configure
39
+ yield(self.config)
40
+ end
16
41
  end
17
42
 
18
43
  require_relative "rest_framework/controller_mixins"
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.6.13
4
+ version: 0.7.0
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: 2022-12-28 00:00:00.000000000 Z
11
+ date: 2022-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails