typical_situation 1.2.0 → 1.3.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 +4 -4
- data/README.md +31 -20
- data/config/locales/typical_situation.en.yml +2 -0
- data/lib/typical_situation/actions.rb +20 -4
- data/lib/typical_situation/identity.rb +4 -4
- data/lib/typical_situation/operations.rb +12 -18
- data/lib/typical_situation/responses.rb +59 -52
- data/lib/typical_situation/serialization.rb +37 -0
- data/lib/typical_situation/version.rb +1 -1
- data/lib/typical_situation.rb +23 -11
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1784b34111a7c2de6a6f429d431d5fc36e00ec033f5e43c1618fc8a198ff534c
|
|
4
|
+
data.tar.gz: 4c40c7fab53aacffff4d30dbe5578fae9019e798384c086b36e4566bdb46baee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e88563fb73ebb702a0b673920e1e85b925799a9287b3336fec394dc8a52952234e296576d7c39a05e015e95611185a1607e7cb0feb005af6a1406caef15b488b
|
|
7
|
+
data.tar.gz: 1a663cdf260368f6ab83b7fadd99128a62cbae89ba67b2d50881232a0f388cc319ae4b5d3b6c4029e47145710be28c344e2608bae30cd2203fcaf5ccb6c95fe8
|
data/README.md
CHANGED
|
@@ -30,7 +30,7 @@ Add to your **Gemfile**:
|
|
|
30
30
|
|
|
31
31
|
### Define your model and methods
|
|
32
32
|
|
|
33
|
-
Basic usage is to declare
|
|
33
|
+
Basic usage is to declare `typical_situation` and define the required `collection` helper. Member lookup uses the model's configured single-column primary key within the security-scoped collection. Missing identifiers return `nil` from the lookup and produce a 404 response.
|
|
34
34
|
|
|
35
35
|
```rb
|
|
36
36
|
class PostsController < ApplicationController
|
|
@@ -45,11 +45,6 @@ class PostsController < ApplicationController
|
|
|
45
45
|
def collection
|
|
46
46
|
current_user.posts
|
|
47
47
|
end
|
|
48
|
-
|
|
49
|
-
# Find a model instance by ID.
|
|
50
|
-
def find_in_collection(id)
|
|
51
|
-
collection.find_by_id(id)
|
|
52
|
-
end
|
|
53
48
|
end
|
|
54
49
|
```
|
|
55
50
|
|
|
@@ -108,6 +103,7 @@ The library is split into modules:
|
|
|
108
103
|
- [operations](https://github.com/mars/typical_situation/blob/master/lib/typical_situation/operations.rb) - loading, changing, & persisting the model
|
|
109
104
|
- [permissions](https://github.com/mars/typical_situation/blob/master/lib/typical_situation/permissions.rb) - handling authorization to records and actions
|
|
110
105
|
- [responses](https://github.com/mars/typical_situation/blob/master/lib/typical_situation/responses.rb) - HTTP responses & redirects
|
|
106
|
+
- [serialization](lib/typical_situation/serialization.rb) - resource representation and JSON root wrapping
|
|
111
107
|
|
|
112
108
|
#### Common Customization Hooks
|
|
113
109
|
|
|
@@ -122,7 +118,7 @@ For index actions, resources move through this pipeline:
|
|
|
122
118
|
5. `paginate_resources` - pagination adapter hook
|
|
123
119
|
6. `prepare_resources` - post-process the loaded records
|
|
124
120
|
|
|
125
|
-
**Scoped Collections** - Restrict the base collection based on user permissions, tenancy, or other security boundaries:
|
|
121
|
+
**Scoped Collections** - Restrict the base collection based on user permissions, tenancy, or other security boundaries. This scope applies to index and member lookup for show, edit, update, and destroy. Filtering, sorting, and pagination remain index-only. New/create use `collection`, so read-visibility conditions do not become creation defaults:
|
|
126
122
|
|
|
127
123
|
```ruby
|
|
128
124
|
def scoped_resource
|
|
@@ -155,11 +151,13 @@ end
|
|
|
155
151
|
**Custom Lookup** - Use different attributes for finding resources:
|
|
156
152
|
|
|
157
153
|
```ruby
|
|
158
|
-
def
|
|
159
|
-
|
|
154
|
+
def find_in_collection(resources, slug)
|
|
155
|
+
resources.find_by(slug: slug)
|
|
160
156
|
end
|
|
161
157
|
```
|
|
162
158
|
|
|
159
|
+
The lookup receives `scoped_resource`; query that relation rather than `collection` to preserve security boundaries. Overriding `find_resource` replaces the security-aware lookup entirely.
|
|
160
|
+
|
|
163
161
|
**Custom Redirects** - Control where users go after actions:
|
|
164
162
|
|
|
165
163
|
```ruby
|
|
@@ -332,7 +330,9 @@ end
|
|
|
332
330
|
|
|
333
331
|
#### Serialization
|
|
334
332
|
|
|
335
|
-
|
|
333
|
+
`TypicalSituation` calls `as_json(root: false)` by default. Override `serializable_resource` to return an unrooted Ruby `Hash` for a member or an `Array` of resource data for a collection. Rails encodes the response once; returning an encoded JSON string raises `TypeError`.
|
|
334
|
+
|
|
335
|
+
`include_root?` controls wrapping with `model_type` for members and `plural_model_type` for collections. Error responses merge model errors under `errors`, independently of the custom serializer.
|
|
336
336
|
|
|
337
337
|
##### Alba
|
|
338
338
|
|
|
@@ -352,16 +352,12 @@ class MockApplePiesController < ApplicationController
|
|
|
352
352
|
private
|
|
353
353
|
|
|
354
354
|
def serializable_resource(resource)
|
|
355
|
-
MockApplePieResource.new(resource).
|
|
355
|
+
MockApplePieResource.new(resource).to_h
|
|
356
356
|
end
|
|
357
357
|
|
|
358
358
|
def collection
|
|
359
359
|
current_user.mock_apple_pies
|
|
360
360
|
end
|
|
361
|
-
|
|
362
|
-
def find_in_collection(id)
|
|
363
|
-
collection.find_by_id(id)
|
|
364
|
-
end
|
|
365
361
|
end
|
|
366
362
|
```
|
|
367
363
|
|
|
@@ -373,15 +369,19 @@ class MockApplePieIndexSerializer < ActiveModel::Serializer
|
|
|
373
369
|
end
|
|
374
370
|
|
|
375
371
|
module TypicalSituation
|
|
376
|
-
module
|
|
372
|
+
module Serialization
|
|
377
373
|
def serializable_resource(resource)
|
|
378
374
|
if action_name == "index"
|
|
379
375
|
ActiveModelSerializers::SerializableResource.new(
|
|
380
376
|
resource,
|
|
381
|
-
each_serializer: MockApplePieIndexSerializer
|
|
382
|
-
|
|
377
|
+
each_serializer: MockApplePieIndexSerializer,
|
|
378
|
+
adapter: :attributes
|
|
379
|
+
).as_json
|
|
383
380
|
else
|
|
384
|
-
ActiveModelSerializers::SerializableResource.new(
|
|
381
|
+
ActiveModelSerializers::SerializableResource.new(
|
|
382
|
+
resource,
|
|
383
|
+
adapter: :attributes
|
|
384
|
+
).as_json
|
|
385
385
|
end
|
|
386
386
|
end
|
|
387
387
|
end
|
|
@@ -401,11 +401,22 @@ class MockApplePiesController < ApplicationController
|
|
|
401
401
|
include TypicalSituation
|
|
402
402
|
|
|
403
403
|
def serializable_resource(resource)
|
|
404
|
-
MockApplePieSerializer.new(resource).serializable_hash
|
|
404
|
+
MockApplePieSerializer.new(resource).serializable_hash.fetch(:data)
|
|
405
405
|
end
|
|
406
406
|
end
|
|
407
407
|
```
|
|
408
408
|
|
|
409
|
+
## Migrating Controller Hooks
|
|
410
|
+
|
|
411
|
+
These hook changes are breaking:
|
|
412
|
+
|
|
413
|
+
- Remove redundant `find_in_collection(id)` overrides, or change them to `find_in_collection(resources, id)` and query the supplied scoped relation.
|
|
414
|
+
- `update_resource(resource, attrs)` must return a success boolean. `create_resource` and `destroy_resource` still return resources; success is determined by `persisted?` and `destroyed?`, respectively. Callback aborts return 422 even when no validation errors were added.
|
|
415
|
+
- Overrides of `respond_as_created`, `respond_as_changed`, and `respond_as_gone` must accept the required `success:` keyword and pass it to `super` when delegating.
|
|
416
|
+
- HTML creation uses `created_so_redirect` and `after_resource_created_path`; updates continue using `changed_so_redirect` and `after_resource_updated_path`.
|
|
417
|
+
- Serialization methods now live in `TypicalSituation::Serialization`, not `Operations`. Return Ruby data from `serializable_resource`, not JSON strings or serializer objects. Overrides of `serialize_resource` should accept `errors: false` instead of an options hash.
|
|
418
|
+
- Failed operations preserve model errors or add `typical_situation.errors.operation_failed` when none exist. Failed HTML destruction sets the error flash; JSON failures do not set flash messages.
|
|
419
|
+
|
|
409
420
|
## Development
|
|
410
421
|
|
|
411
422
|
After checking out the repo, run `bin/setup` to install dependencies.
|
|
@@ -35,8 +35,12 @@ module TypicalSituation
|
|
|
35
35
|
get_resource
|
|
36
36
|
raise TypicalSituation::ActionForbidden unless authorized?(:update, @resource)
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
success = normalize_operation_result(
|
|
39
|
+
@resource,
|
|
40
|
+
success: update_resource(@resource, update_params)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
respond_as_changed(success: success)
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
def destroy
|
|
@@ -44,14 +48,26 @@ module TypicalSituation
|
|
|
44
48
|
raise TypicalSituation::ActionForbidden unless authorized?(:destroy, @resource)
|
|
45
49
|
|
|
46
50
|
destroy_resource(@resource)
|
|
47
|
-
|
|
51
|
+
|
|
52
|
+
success = normalize_operation_result(
|
|
53
|
+
@resource,
|
|
54
|
+
success: @resource.destroyed?
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
respond_as_gone(success: success)
|
|
48
58
|
end
|
|
49
59
|
|
|
50
60
|
def create
|
|
51
61
|
raise TypicalSituation::ActionForbidden unless authorized?(:create)
|
|
52
62
|
|
|
53
63
|
@resource = create_resource(create_params)
|
|
54
|
-
|
|
64
|
+
|
|
65
|
+
success = normalize_operation_result(
|
|
66
|
+
@resource,
|
|
67
|
+
success: @resource.persisted?
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
respond_as_created(success: success)
|
|
55
71
|
end
|
|
56
72
|
end
|
|
57
73
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module TypicalSituation
|
|
4
|
-
#
|
|
4
|
+
# Model identity, collection, and request configuration.
|
|
5
5
|
module Identity
|
|
6
6
|
protected
|
|
7
7
|
|
|
@@ -43,9 +43,9 @@ module TypicalSituation
|
|
|
43
43
|
raise(NotImplementedError, "#collection must be defined in the TypicalSituation implementation.")
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
-
# Find a model instance by
|
|
47
|
-
def find_in_collection(
|
|
48
|
-
|
|
46
|
+
# Find a model instance by its configured primary key.
|
|
47
|
+
def find_in_collection(resources, identifier)
|
|
48
|
+
resources.find_by(resources.primary_key => identifier)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def include_root?
|
|
@@ -11,7 +11,7 @@ module TypicalSituation
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def find_resource(param)
|
|
14
|
-
find_in_collection(param)
|
|
14
|
+
find_in_collection(scoped_resource, param)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def default_sorting_attribute
|
|
@@ -86,7 +86,6 @@ module TypicalSituation
|
|
|
86
86
|
|
|
87
87
|
def destroy_resource(resource)
|
|
88
88
|
resource.destroy
|
|
89
|
-
collection.reload if resource.errors.empty?
|
|
90
89
|
resource
|
|
91
90
|
end
|
|
92
91
|
|
|
@@ -102,28 +101,23 @@ module TypicalSituation
|
|
|
102
101
|
@model_class ||= model_type.to_s.camelize.constantize
|
|
103
102
|
end
|
|
104
103
|
|
|
105
|
-
def serialize_resource(resource, options = {})
|
|
106
|
-
serializable_resource(resource).to_json(options.merge(root: include_root?))
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def serialize_resources(resources)
|
|
110
|
-
if include_root?
|
|
111
|
-
return {plural_model_type => serializable_resource(resources)}
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
serializable_resource(resources).to_json(root: false)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def serializable_resource(resource)
|
|
118
|
-
resource
|
|
119
|
-
end
|
|
120
|
-
|
|
121
104
|
def id_param
|
|
122
105
|
params[:id]
|
|
123
106
|
end
|
|
124
107
|
|
|
125
108
|
private
|
|
126
109
|
|
|
110
|
+
def normalize_operation_result(resource, success:)
|
|
111
|
+
if !success && resource.errors.empty?
|
|
112
|
+
resource.errors.add(
|
|
113
|
+
:base,
|
|
114
|
+
I18n.t("typical_situation.errors.operation_failed")
|
|
115
|
+
)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
success
|
|
119
|
+
end
|
|
120
|
+
|
|
127
121
|
def apply_sorting(resources)
|
|
128
122
|
return resources unless default_sorting_attribute
|
|
129
123
|
resources.order(default_sorting_attribute => default_sorting_direction)
|
|
@@ -39,42 +39,40 @@ module TypicalSituation
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def respond_as_changed
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
end
|
|
42
|
+
def respond_as_changed(success:)
|
|
43
|
+
return respond_as_failure(:update) unless success
|
|
44
|
+
|
|
45
|
+
respond_to do |format|
|
|
46
|
+
yield(format) if block_given?
|
|
47
|
+
|
|
48
|
+
format.html do
|
|
49
|
+
set_success_flash(:update)
|
|
50
|
+
set_single_instance
|
|
51
|
+
changed_so_redirect || render
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
format.json do
|
|
55
|
+
render json: serialize_resource(@resource)
|
|
57
56
|
end
|
|
58
57
|
end
|
|
59
58
|
end
|
|
60
59
|
|
|
61
|
-
def respond_as_created
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
end
|
|
60
|
+
def respond_as_created(success:)
|
|
61
|
+
return respond_as_failure(:create) unless success
|
|
62
|
+
|
|
63
|
+
respond_to do |format|
|
|
64
|
+
yield(format) if block_given?
|
|
65
|
+
|
|
66
|
+
format.html do
|
|
67
|
+
set_success_flash(:create)
|
|
68
|
+
set_single_instance
|
|
69
|
+
created_so_redirect || render
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
format.json do
|
|
73
|
+
render json: serialize_resource(@resource),
|
|
74
|
+
location: location_url,
|
|
75
|
+
status: :created
|
|
78
76
|
end
|
|
79
77
|
end
|
|
80
78
|
end
|
|
@@ -89,27 +87,25 @@ module TypicalSituation
|
|
|
89
87
|
status: :unprocessable_entity
|
|
90
88
|
end
|
|
91
89
|
format.json do
|
|
92
|
-
render json: serialize_resource(@resource,
|
|
90
|
+
render json: serialize_resource(@resource, errors: true),
|
|
93
91
|
status: :unprocessable_entity
|
|
94
92
|
end
|
|
95
93
|
end
|
|
96
94
|
end
|
|
97
95
|
|
|
98
|
-
def respond_as_gone
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
head :no_content
|
|
112
|
-
end
|
|
96
|
+
def respond_as_gone(success:)
|
|
97
|
+
return respond_as_failure(:destroy) unless success
|
|
98
|
+
|
|
99
|
+
respond_to do |format|
|
|
100
|
+
yield(format) if block_given?
|
|
101
|
+
|
|
102
|
+
format.html do
|
|
103
|
+
set_single_instance
|
|
104
|
+
gone_so_redirect || render
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
format.json do
|
|
108
|
+
head :no_content
|
|
113
109
|
end
|
|
114
110
|
end
|
|
115
111
|
end
|
|
@@ -135,17 +131,22 @@ module TypicalSituation
|
|
|
135
131
|
end
|
|
136
132
|
|
|
137
133
|
def after_resource_created_path(resource)
|
|
138
|
-
{action: :show, id: resource.
|
|
134
|
+
{action: :show, id: resource.to_param}
|
|
139
135
|
end
|
|
140
136
|
|
|
141
137
|
def after_resource_updated_path(resource)
|
|
142
|
-
{action: :show, id: resource.
|
|
138
|
+
{action: :show, id: resource.to_param}
|
|
143
139
|
end
|
|
144
140
|
|
|
145
141
|
def after_resource_destroyed_path(_resource)
|
|
146
142
|
{action: :index}
|
|
147
143
|
end
|
|
148
144
|
|
|
145
|
+
def created_so_redirect
|
|
146
|
+
redirect_to after_resource_created_path(@resource)
|
|
147
|
+
true
|
|
148
|
+
end
|
|
149
|
+
|
|
149
150
|
# HTML response when @resource saved or updated.
|
|
150
151
|
def changed_so_redirect
|
|
151
152
|
redirect_to after_resource_updated_path(@resource)
|
|
@@ -154,10 +155,16 @@ module TypicalSituation
|
|
|
154
155
|
|
|
155
156
|
# HTML response when @resource deleted.
|
|
156
157
|
def gone_so_redirect
|
|
157
|
-
|
|
158
|
-
set_success_flash(:destroy) unless has_errors?
|
|
158
|
+
set_success_flash(:destroy)
|
|
159
159
|
redirect_to after_resource_destroyed_path(@resource)
|
|
160
160
|
true
|
|
161
161
|
end
|
|
162
|
+
|
|
163
|
+
private
|
|
164
|
+
|
|
165
|
+
def respond_as_failure(action)
|
|
166
|
+
set_error_flash if action == :destroy && request.format.html?
|
|
167
|
+
respond_as_error
|
|
168
|
+
end
|
|
162
169
|
end
|
|
163
170
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TypicalSituation
|
|
4
|
+
module Serialization
|
|
5
|
+
protected
|
|
6
|
+
|
|
7
|
+
def serialize_resource(resource, errors: false)
|
|
8
|
+
data = serialization_data(resource, Hash)
|
|
9
|
+
data = data.merge("errors" => resource.errors.as_json) if errors
|
|
10
|
+
|
|
11
|
+
include_root? ? {model_type => data} : data
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def serialize_resources(resources)
|
|
15
|
+
data = serialization_data(resources, Array)
|
|
16
|
+
|
|
17
|
+
include_root? ? {plural_model_type => data} : data
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def serializable_resource(resource)
|
|
21
|
+
resource.as_json(root: false)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def serialization_data(resource, expected_type)
|
|
27
|
+
data = serializable_resource(resource)
|
|
28
|
+
|
|
29
|
+
unless data.is_a?(expected_type)
|
|
30
|
+
raise TypeError,
|
|
31
|
+
"serializable_resource must return #{expected_type}, got #{data.class}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
data
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/typical_situation.rb
CHANGED
|
@@ -7,19 +7,28 @@ require "typical_situation/flash_messages"
|
|
|
7
7
|
require "typical_situation/actions"
|
|
8
8
|
require "typical_situation/operations"
|
|
9
9
|
require "typical_situation/responses"
|
|
10
|
+
require "typical_situation/serialization"
|
|
10
11
|
|
|
11
12
|
module TypicalSituation
|
|
12
13
|
class Error < StandardError; end
|
|
13
14
|
class ActionForbidden < Error; end
|
|
14
15
|
|
|
16
|
+
ACTION_NAMES = Actions.public_instance_methods(false).map(&:to_s).freeze
|
|
17
|
+
|
|
15
18
|
include Identity
|
|
16
19
|
include Permissions
|
|
17
20
|
include FlashMessages
|
|
18
21
|
include Operations
|
|
19
22
|
include Responses
|
|
23
|
+
include Serialization
|
|
20
24
|
|
|
21
25
|
def self.included(base)
|
|
22
26
|
add_rescues(base)
|
|
27
|
+
|
|
28
|
+
base.class_attribute :typical_action_names,
|
|
29
|
+
instance_accessor: false,
|
|
30
|
+
default: ACTION_NAMES
|
|
31
|
+
|
|
23
32
|
base.extend(ClassMethods)
|
|
24
33
|
end
|
|
25
34
|
|
|
@@ -37,20 +46,23 @@ module TypicalSituation
|
|
|
37
46
|
# :post
|
|
38
47
|
# end
|
|
39
48
|
def typical_situation(model_type_symbol, only: nil)
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
actions = only.nil? ? ACTION_NAMES : Array(only).map(&:to_s)
|
|
50
|
+
unknown = actions - ACTION_NAMES
|
|
51
|
+
|
|
52
|
+
if unknown.any?
|
|
53
|
+
raise ArgumentError, "Unknown actions: #{unknown.join(", ")}"
|
|
42
54
|
end
|
|
55
|
+
|
|
56
|
+
self.typical_action_names = actions.freeze
|
|
57
|
+
|
|
58
|
+
define_method(:model_type) { model_type_symbol }
|
|
43
59
|
protected :model_type
|
|
44
60
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
end
|
|
51
|
-
else
|
|
52
|
-
include TypicalSituation::Actions
|
|
53
|
-
end
|
|
61
|
+
include TypicalSituation::Actions
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def action_methods
|
|
65
|
+
super - (ACTION_NAMES - typical_action_names)
|
|
54
66
|
end
|
|
55
67
|
|
|
56
68
|
def typical_rest(model_type_symbol)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typical_situation
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mars Hall
|
|
@@ -213,6 +213,7 @@ files:
|
|
|
213
213
|
- lib/typical_situation/operations.rb
|
|
214
214
|
- lib/typical_situation/permissions.rb
|
|
215
215
|
- lib/typical_situation/responses.rb
|
|
216
|
+
- lib/typical_situation/serialization.rb
|
|
216
217
|
- lib/typical_situation/version.rb
|
|
217
218
|
homepage: https://github.com/apsislabs/typical_situation
|
|
218
219
|
licenses: []
|