typical_situation 1.0.2 → 1.1.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: 59384fee031d1440a474689f99be97760aedc645343e4febf4d1356ed05ee801
4
- data.tar.gz: '08b482a57e976dbe1ac86604648a4f237346c09db88c672483dfae604d566cf1'
3
+ metadata.gz: 48bf00bdaee8edb5e3fbf54b68ca577960068cae3dac7804ca56169d738c834c
4
+ data.tar.gz: e11a3d08dd5991937bb08b2b3a731d8bd67f91b19658c25239bef18e60e4f921
5
5
  SHA512:
6
- metadata.gz: dbcec21abd36a2da29b901bb2ffcb0468b6cf4170b4e974bef1cd640d174813c557fa8a87bddcda23e92c5709ea5c89c4fa39de7968f62ea08d5db6ac99a01a3
7
- data.tar.gz: d12f5d0e3d6408a7060d46704e8dbe47cc516119fd7ae360e863bd3d00592def5e0ce99ac2bd2e6b491575284022469299689fef943368831003da8235c0a5a3
6
+ metadata.gz: 584cecff5e2be5ac3201983c4a2e0fbe1ec69cf5cd7cc18c91aa2d267bb73a8680194137774889fe9cd546c3f3dc55ee35bcef53ff643e8b5ff54eb741a7e6fe
7
+ data.tar.gz: e31342f32bc78ce7aecf165ce64c51fb38f1fd3d8031ffeec891f38b972945fc0da002227a919afc7942ca61179fe3de4e4dbf4fe3f82af77cc9a014b7ed1b14
data/README.md CHANGED
@@ -8,15 +8,17 @@ A Ruby mixin (module) providing the seven standard resource actions & responses
8
8
 
9
9
  Tested in:
10
10
 
11
- - Rails 7.0
12
- - Rails 7.1
11
+ - Rails 7.2
13
12
  - Rails 8.0
13
+ - Rails 8.1
14
14
 
15
15
  Against Ruby versions:
16
16
 
17
+ - 3.1
17
18
  - 3.2
18
19
  - 3.3
19
20
  - 3.4
21
+ - 4.0
20
22
 
21
23
  Add to your **Gemfile**:
22
24
 
@@ -109,7 +111,17 @@ The library is split into modules:
109
111
 
110
112
  #### Common Customization Hooks
111
113
 
112
- **Scoped Collections** - Filter the collection based on user permissions or other criteria:
114
+ Most customization hooks are intended to be overridden as `private` or `protected` controller methods so they do not become public controller actions.
115
+
116
+ For index actions, resources move through this pipeline:
117
+
118
+ 1. `collection` - base relation from the host controller
119
+ 2. `scoped_resource` - visibility/tenant/security scoping
120
+ 3. `prepare_resources` - search or filter transforms
121
+ 4. `apply_sorting` - default sorting from `default_sorting_attribute`
122
+ 5. `paginate_resources` - pagination adapter hook
123
+
124
+ **Scoped Collections** - Restrict the base collection based on user permissions, tenancy, or other security boundaries:
113
125
 
114
126
  ```ruby
115
127
  def scoped_resource
@@ -121,6 +133,16 @@ def scoped_resource
121
133
  end
122
134
  ```
123
135
 
136
+ **Search and Filtering** - Apply request-driven filters after scoping and before sorting/pagination:
137
+
138
+ ```ruby
139
+ def prepare_resources(resources)
140
+ resources = resources.where(status: params[:status]) if params[:status].present?
141
+ resources = resources.where("title ILIKE ?", "%#{params[:q]}%") if params[:q].present?
142
+ resources
143
+ end
144
+ ```
145
+
124
146
  **Custom Lookup** - Use different attributes for finding resources:
125
147
 
126
148
  ```ruby
@@ -439,6 +461,19 @@ Start an interactive console to experiment with the gem:
439
461
  bundle exec irb -r typical_situation
440
462
  ```
441
463
 
464
+ ### Releasing
465
+
466
+ Create a release from `main`:
467
+
468
+ ```sh
469
+ bin/release {major|minor|patch|pre}
470
+ git push --follow-tags
471
+ ```
472
+
473
+ The release script validates the repository, bumps the version, creates a git tag.
474
+
475
+ Publishing to RubyGems and creating a GitHub Release are handled automatically by GitHub Actions.
476
+
442
477
  ## Contributing
443
478
 
444
479
  Bug reports and pull requests are welcome on GitHub at https://github.com/apsislabs/typical_situation.
@@ -1,4 +1,4 @@
1
- require 'rails/engine'
1
+ require "rails/engine"
2
2
 
3
3
  module TypicalSituation
4
4
  class Engine < Rails::Engine
@@ -3,6 +3,8 @@
3
3
  module TypicalSituation
4
4
  # These Identity methods must be defined for each implementation.
5
5
  module Identity
6
+ protected
7
+
6
8
  # Symbolized, underscored version of the model (class) to use.
7
9
  def model_type
8
10
  raise(NotImplementedError, "#model_type must be defined in the TypicalSituation implementation.")
@@ -4,6 +4,8 @@ module TypicalSituation
4
4
  # Model operations.
5
5
  # Assume that we're working w/ an ActiveRecord association collection.
6
6
  module Operations
7
+ protected
8
+
7
9
  def scoped_resource
8
10
  collection
9
11
  end
@@ -29,11 +31,11 @@ module TypicalSituation
29
31
  end
30
32
 
31
33
  def get_resource
32
- if (@resource = find_resource(params[:id]))
34
+ if (@resource = find_resource(id_param))
33
35
  set_single_instance
34
36
  @resource
35
37
  else
36
- raise ActiveRecord::RecordNotFound, "Could not find #{model_class}( id:#{params[:id].inspect} )"
38
+ raise ActiveRecord::RecordNotFound, "Could not find #{model_class}( id:#{id_param.inspect} )"
37
39
  end
38
40
  end
39
41
 
@@ -41,12 +43,29 @@ module TypicalSituation
41
43
  !@resource.errors.empty?
42
44
  end
43
45
 
46
+ # Collection pipeline lifecycle:
47
+ # collection - base relation (user-defined, required)
48
+ # scoped_resource - wraps/scopes the collection (visibility, tenancy, PHI)
49
+ # prepare_resources - standardized additional transforms (search, filter)
50
+ # apply_sorting - applies ORDER BY
51
+ # paginate_resources - applies pagination
52
+ #
53
+ # Override +prepare_resources+ in host controllers to add search/filter
54
+ # behavior without touching sorting or pagination hooks.
44
55
  def get_resources
45
- @resources = paginate_resources(apply_sorting(scoped_resource))
56
+ resources = scoped_resource
57
+ resources = prepare_resources(resources)
58
+ resources = apply_sorting(resources)
59
+ resources = paginate_resources(resources)
60
+ @resources = resources
46
61
  set_collection_instance
47
62
  @resources
48
63
  end
49
64
 
65
+ def prepare_resources(resources)
66
+ resources
67
+ end
68
+
50
69
  def new_resource
51
70
  @resource = collection.build
52
71
  end
@@ -93,16 +112,8 @@ module TypicalSituation
93
112
  resource
94
113
  end
95
114
 
96
- # Set the singular instance variable named after the model. Modules are delimited with "_".
97
- # Example: a MockApplePie resource is set to ivar @mock_apple_pie.
98
- def set_single_instance
99
- instance_variable_set(:"@#{model_type.to_s.gsub("/", "__")}", @resource)
100
- end
101
-
102
- # Set the plural instance variable named after the model. Modules are delimited with "_".
103
- # Example: a MockApplePie resource collection is set to ivar @mock_apple_pies.
104
- def set_collection_instance
105
- instance_variable_set(:"@#{model_type.to_s.gsub("/", "__").pluralize}", @resources)
115
+ def id_param
116
+ params[:id]
106
117
  end
107
118
 
108
119
  private
@@ -111,5 +122,15 @@ module TypicalSituation
111
122
  return resources unless default_sorting_attribute
112
123
  resources.order(default_sorting_attribute => default_sorting_direction)
113
124
  end
125
+
126
+ # Sets the singular ivar named after the model (modules delimited with "__").
127
+ def set_single_instance
128
+ instance_variable_set(:"@#{model_type.to_s.gsub("/", "__")}", @resource)
129
+ end
130
+
131
+ # Sets the plural ivar named after the model (modules delimited with "__").
132
+ def set_collection_instance
133
+ instance_variable_set(:"@#{model_type.to_s.gsub("/", "__").pluralize}", @resources)
134
+ end
114
135
  end
115
136
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module TypicalSituation
4
4
  module Permissions
5
+ protected
6
+
5
7
  def authorized?(_action, _resource = nil)
6
8
  true
7
9
  end
@@ -3,6 +3,8 @@
3
3
  module TypicalSituation
4
4
  # Rails MIME responses.
5
5
  module Responses
6
+ protected
7
+
6
8
  # Return the collection as HTML or JSON
7
9
  #
8
10
  def respond_with_resources
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TypicalSituation
4
- VERSION = "1.0.2"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'typical_situation/engine'
4
- require 'typical_situation/identity'
5
- require 'typical_situation/permissions'
6
- require 'typical_situation/flash_messages'
7
- require 'typical_situation/actions'
8
- require 'typical_situation/operations'
9
- require 'typical_situation/responses'
3
+ require "typical_situation/engine"
4
+ require "typical_situation/identity"
5
+ require "typical_situation/permissions"
6
+ require "typical_situation/flash_messages"
7
+ require "typical_situation/actions"
8
+ require "typical_situation/operations"
9
+ require "typical_situation/responses"
10
10
 
11
11
  module TypicalSituation
12
12
  class Error < StandardError; end
@@ -40,6 +40,7 @@ module TypicalSituation
40
40
  define_method :model_type do
41
41
  model_type_symbol
42
42
  end
43
+ protected :model_type
43
44
 
44
45
  if only
45
46
  only.each do |action|
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.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mars Hall
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.0
19
+ version: 7.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.0
26
+ version: 7.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: appraisal
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +53,21 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.2.0
55
55
  - !ruby/object:Gem::Dependency
56
- name: byebug
56
+ name: bump
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: debug
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
@@ -210,7 +224,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
210
224
  requirements:
211
225
  - - ">="
212
226
  - !ruby/object:Gem::Version
213
- version: 3.0.0
227
+ version: 3.1.0
214
228
  required_rubygems_version: !ruby/object:Gem::Requirement
215
229
  requirements:
216
230
  - - ">="