rest_framework 0.6.13 → 0.7.0

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