plutonium 0.23.4 → 0.23.5

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/plutonium.css +2 -2
  3. data/config/initializers/sqlite_json_alias.rb +1 -1
  4. data/docs/.vitepress/config.ts +60 -19
  5. data/docs/guide/cursor-rules.md +75 -0
  6. data/docs/guide/deep-dive/authorization.md +189 -0
  7. data/docs/guide/{getting-started → deep-dive}/resources.md +137 -0
  8. data/docs/guide/getting-started/{installation.md → 01-installation.md} +0 -105
  9. data/docs/guide/index.md +28 -0
  10. data/docs/guide/introduction/02-core-concepts.md +440 -0
  11. data/docs/guide/tutorial/01-project-setup.md +75 -0
  12. data/docs/guide/tutorial/02-creating-a-feature-package.md +45 -0
  13. data/docs/guide/tutorial/03-defining-resources.md +90 -0
  14. data/docs/guide/tutorial/04-creating-a-portal.md +101 -0
  15. data/docs/guide/tutorial/05-customizing-the-ui.md +128 -0
  16. data/docs/guide/tutorial/06-adding-custom-actions.md +101 -0
  17. data/docs/guide/tutorial/07-implementing-authorization.md +90 -0
  18. data/docs/index.md +24 -31
  19. data/docs/modules/action.md +190 -0
  20. data/docs/modules/authentication.md +236 -0
  21. data/docs/modules/configuration.md +599 -0
  22. data/docs/modules/controller.md +398 -0
  23. data/docs/modules/core.md +316 -0
  24. data/docs/modules/definition.md +876 -0
  25. data/docs/modules/display.md +759 -0
  26. data/docs/modules/form.md +605 -0
  27. data/docs/modules/generator.md +288 -0
  28. data/docs/modules/index.md +167 -0
  29. data/docs/modules/interaction.md +470 -0
  30. data/docs/modules/package.md +151 -0
  31. data/docs/modules/policy.md +176 -0
  32. data/docs/modules/portal.md +710 -0
  33. data/docs/modules/query.md +287 -0
  34. data/docs/modules/resource_record.md +618 -0
  35. data/docs/modules/routing.md +641 -0
  36. data/docs/modules/table.md +293 -0
  37. data/docs/modules/ui.md +631 -0
  38. data/docs/public/plutonium.mdc +667 -0
  39. data/lib/generators/pu/core/assets/assets_generator.rb +0 -5
  40. data/lib/plutonium/ui/display/resource.rb +7 -2
  41. data/lib/plutonium/ui/table/resource.rb +8 -3
  42. data/lib/plutonium/version.rb +1 -1
  43. metadata +36 -9
  44. data/docs/guide/getting-started/authorization.md +0 -296
  45. data/docs/guide/getting-started/core-concepts.md +0 -432
  46. data/docs/guide/getting-started/index.md +0 -21
  47. data/docs/guide/tutorial.md +0 -401
  48. /data/docs/guide/{what-is-plutonium.md → introduction/01-what-is-plutonium.md} +0 -0
@@ -59,9 +59,14 @@ module Plutonium
59
59
  column_definition = resource_definition.defined_columns[name] || {}
60
60
  column_options = column_definition[:options] || {}
61
61
 
62
+ # Check for conditional rendering
63
+ condition = column_options[:condition] || display_options[:condition] || field_options[:condition]
64
+ conditionally_hidden = condition && !instance_exec(&condition)
65
+ next if conditionally_hidden
66
+
62
67
  tag = column_options[:as] || display_definition[:as] || field_options[:as]
63
- display_tag_attributes = display_options.except(:wrapper, :as)
64
- column_tag_attributes = column_options.except(:wrapper, :as, :align)
68
+ display_tag_attributes = display_options.except(:wrapper, :as, :condition)
69
+ column_tag_attributes = column_options.except(:wrapper, :as, :align, :condition)
65
70
  tag_attributes = display_tag_attributes.merge(column_tag_attributes)
66
71
  tag_block = column_definition[:block] || ->(wrapped_object, key) {
67
72
  f = wrapped_object.field(key)
@@ -69,7 +74,7 @@ module Plutonium
69
74
  f.send(:"#{tag}_tag", **tag_attributes)
70
75
  }
71
76
 
72
- field_options = field_options.merge(**column_options.slice(:align))
77
+ field_options = field_options.except(:condition).merge(**column_options.slice(:align))
73
78
  table.column name,
74
79
  **field_options,
75
80
  sort_params: current_query_object.sort_params_for(name),
@@ -1,5 +1,5 @@
1
1
  module Plutonium
2
- VERSION = "0.23.4"
2
+ VERSION = "0.23.5"
3
3
  NEXT_MAJOR_VERSION = VERSION.split(".").tap { |v|
4
4
  v[1] = v[1].to_i + 1
5
5
  v[2] = 0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plutonium
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.4
4
+ version: 0.23.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-05-27 00:00:00.000000000 Z
11
+ date: 2025-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk
@@ -493,21 +493,48 @@ files:
493
493
  - docs/.vitepress/theme/custom.css
494
494
  - docs/.vitepress/theme/index.ts
495
495
  - docs/api-examples.md
496
- - docs/guide/getting-started/authorization.md
497
- - docs/guide/getting-started/core-concepts.md
498
- - docs/guide/getting-started/index.md
499
- - docs/guide/getting-started/installation.md
500
- - docs/guide/getting-started/resources.md
501
- - docs/guide/tutorial.md
502
- - docs/guide/what-is-plutonium.md
496
+ - docs/guide/cursor-rules.md
497
+ - docs/guide/deep-dive/authorization.md
498
+ - docs/guide/deep-dive/resources.md
499
+ - docs/guide/getting-started/01-installation.md
500
+ - docs/guide/index.md
501
+ - docs/guide/introduction/01-what-is-plutonium.md
502
+ - docs/guide/introduction/02-core-concepts.md
503
+ - docs/guide/tutorial/01-project-setup.md
504
+ - docs/guide/tutorial/02-creating-a-feature-package.md
505
+ - docs/guide/tutorial/03-defining-resources.md
506
+ - docs/guide/tutorial/04-creating-a-portal.md
507
+ - docs/guide/tutorial/05-customizing-the-ui.md
508
+ - docs/guide/tutorial/06-adding-custom-actions.md
509
+ - docs/guide/tutorial/07-implementing-authorization.md
503
510
  - docs/index.md
504
511
  - docs/markdown-examples.md
512
+ - docs/modules/action.md
513
+ - docs/modules/authentication.md
514
+ - docs/modules/configuration.md
515
+ - docs/modules/controller.md
516
+ - docs/modules/core.md
517
+ - docs/modules/definition.md
518
+ - docs/modules/display.md
519
+ - docs/modules/form.md
520
+ - docs/modules/generator.md
521
+ - docs/modules/index.md
522
+ - docs/modules/interaction.md
523
+ - docs/modules/package.md
524
+ - docs/modules/policy.md
525
+ - docs/modules/portal.md
526
+ - docs/modules/query.md
527
+ - docs/modules/resource_record.md
528
+ - docs/modules/routing.md
529
+ - docs/modules/table.md
530
+ - docs/modules/ui.md
505
531
  - docs/public/android-chrome-192x192.png
506
532
  - docs/public/android-chrome-512x512.png
507
533
  - docs/public/apple-touch-icon.png
508
534
  - docs/public/favicon-16x16.png
509
535
  - docs/public/favicon-32x32.png
510
536
  - docs/public/favicon.ico
537
+ - docs/public/plutonium.mdc
511
538
  - docs/public/plutonium.png
512
539
  - docs/public/site.webmanifest
513
540
  - docs/public/templates/base.rb
@@ -1,296 +0,0 @@
1
- # Authorization and Access Control
2
-
3
- Plutonium provides a robust authorization system built on top of [Action Policy](https://actionpolicy.evilmartians.io/), offering fine-grained access control, resource scoping, and entity-based authorization.
4
-
5
- ## Overview
6
-
7
- Authorization in Plutonium operates at multiple levels:
8
- - Resource-level policies
9
- - Action-based permissions
10
- - Entity-based scoping
11
- - Attribute-level access control
12
-
13
- ## Basic Policy Definition
14
-
15
- Every resource in Plutonium requires a policy. Here's a basic example:
16
-
17
- ```ruby
18
- class BlogPolicy < ResourcePolicy
19
- # Core CRUD Permissions
20
-
21
- def create?
22
- # All authenticated users can create blogs
23
- true
24
- end
25
-
26
- def read?
27
- # Allow anyone to read blogs
28
- true
29
- end
30
-
31
- def update?
32
- # Allow only the blog owner to update
33
- owner?
34
- end
35
-
36
- def destroy?
37
- # Allow only the blog owner or admins to destroy
38
- owner? || user.admin?
39
- end
40
-
41
- # Attribute Control
42
-
43
- def permitted_attributes_for_create
44
- [:title, :content, :category]
45
- end
46
-
47
- def permitted_attributes_for_read
48
- [:title, :content, :category, :created_at, :updated_at, :user_id]
49
- end
50
-
51
- def permitted_attributes_for_update
52
- [:title, :content, :category]
53
- end
54
-
55
- # Association Access
56
-
57
- def permitted_associations
58
- [:comments]
59
- end
60
-
61
- private
62
-
63
- def owner?
64
- record.user_id == user.id
65
- end
66
- end
67
- ```
68
-
69
- ## Default Behaviors in Plutonium Policies
70
-
71
- ::: info Overview
72
- Plutonium's Policy system implements a secure-by-default pattern with clear inheritance chains for both permissions and attribute access.
73
- :::
74
-
75
- ### Permission Defaults
76
-
77
- Permission methods follow two key patterns: core permissions that default to `false`, and derived permissions that inherit from core ones.
78
-
79
- #### Core Permission Chain
80
-
81
- ```mermaid
82
- graph TD
83
- subgraph Core Permissions
84
- A[create? ❌] --> B[update? ❌]
85
- A --> C[destroy? ❌]
86
- D[read? ❌] --> E[index? ❌]
87
- D --> F[show? ❌]
88
- end
89
- ```
90
-
91
- ::: warning Security First
92
- All core permissions (`create?` and `read?`) default to `false`. You must explicitly override these to grant access.
93
- ```ruby
94
- # Default implementations
95
- def create?
96
- false
97
- end
98
-
99
- def read?
100
- false
101
- end
102
- ```
103
- :::
104
-
105
- #### Permission Inheritance
106
-
107
- ::: code-group
108
- ```ruby [Action Methods]
109
- def update?
110
- create? # Inherits from create?
111
- end
112
-
113
- def destroy?
114
- create? # Inherits from create?
115
- end
116
-
117
- def index?
118
- read? # Inherits from read?
119
- end
120
-
121
- def show?
122
- read? # Inherits from read?
123
- end
124
- ```
125
-
126
- ```ruby [Helper Methods]
127
- def new?
128
- create? # Matches create?
129
- end
130
-
131
- def edit?
132
- update? # Matches update?
133
- end
134
-
135
- def search?
136
- index? # Matches index?
137
- end
138
- ```
139
- :::
140
-
141
- ### Attribute Permission Defaults
142
-
143
- Attribute permissions also follow an inheritance pattern, but with auto-detection in development:
144
-
145
- ::: details Inheritance Chain
146
- ```mermaid
147
- graph TD
148
- subgraph Core Attributes
149
- A[permitted_attributes_for_create] --> B[permitted_attributes_for_update]
150
- C[permitted_attributes_for_read] --> D[permitted_attributes_for_show]
151
- C --> E[permitted_attributes_for_index]
152
- end
153
- ```
154
- :::
155
-
156
- #### Core Implementation Details
157
-
158
- ::: code-group
159
- ```ruby [Create Attributes]
160
- def permitted_attributes_for_create
161
- # Auto-detects fields but excludes system columns
162
- autodetect_permitted_fields(:permitted_attributes_for_create) - [
163
- resource_class.primary_key.to_sym,
164
- :created_at,
165
- :updated_at
166
- ]
167
- end
168
- ```
169
-
170
- ```ruby [Read Attributes]
171
- def permitted_attributes_for_read
172
- # Auto-detects all fields
173
- autodetect_permitted_fields(:permitted_attributes_for_read)
174
- end
175
- ```
176
-
177
- ```ruby [Update Attributes]
178
- def permitted_attributes_for_update
179
- # Inherits from create
180
- permitted_attributes_for_create
181
- end
182
- ```
183
- :::
184
-
185
- ::: danger Auto-detection Warning
186
- The default attribute detection:
187
- - Only works in development
188
- - Raises errors in other environments
189
- - Shows warning messages
190
- - Must be overridden in production
191
- :::
192
-
193
- ### Association Defaults
194
-
195
- By default, no associations are permitted:
196
-
197
- ```ruby
198
- def permitted_associations
199
- [] # Must be explicitly defined
200
- end
201
- ```
202
-
203
- ### Context Object Defaults
204
-
205
- Two built-in authorization contexts:
206
-
207
- ::: code-group
208
- ```ruby [Required Context]
209
- # User must be present
210
- authorize :user, allow_nil: false
211
- ```
212
-
213
- ```ruby [Optional Context]
214
- # Entity scope is optional
215
- authorize :entity_scope, allow_nil: true
216
- ```
217
- :::
218
-
219
- #### Default Scoping Behavior
220
-
221
- When an entity scope exists, records are automatically filtered:
222
-
223
- ```ruby
224
- relation_scope do |relation|
225
- next relation unless entity_scope
226
- relation.associated_with(entity_scope)
227
- end
228
- ```
229
-
230
- #### Adding Custom Contexts
231
-
232
- You can add additional authorization contexts:
233
-
234
- ::: code-group
235
- ```ruby [Policy]
236
- class BlogPolicy < ResourcePolicy
237
- authorize :ability, allow_nil: true
238
-
239
- def promote?
240
- user.admin? && ability&.can?(:promote, record)
241
- end
242
- end
243
- ```
244
-
245
- ```ruby [Controller]
246
- class BlogsController < ResourceController
247
- authorize :ability, through: :current_ability
248
-
249
- private
250
-
251
- def current_ability
252
- @current_ability ||= Ability.new(current_user)
253
- end
254
- end
255
- ```
256
- :::
257
-
258
- ## Quick Reference
259
-
260
- | Method Type | Default | Inherits From |
261
- |------------|---------|---------------|
262
- | create? | false | - |
263
- | read? | false | - |
264
- | update? | false | create? |
265
- | destroy? | false | create? |
266
- | index? | false | read? |
267
- | show? | false | read? |
268
- | attributes_for_create | auto* | - |
269
- | attributes_for_read | auto* | - |
270
- | attributes_for_update | auto* | create |
271
- | associations | [] | - |
272
-
273
- ::: warning
274
- \*Auto-detection only works in development
275
- :::
276
-
277
- ## Security Best Practices
278
-
279
- ### 1. Never Skip Authorization
280
-
281
- Plutonium controllers automatically verify authorization:
282
-
283
- ```ruby
284
- class BlogsController < ResourceController
285
- def show
286
- # This will raise an error if you forget to authorize
287
- # authorize! resource_record
288
- render :show
289
- end
290
- end
291
- ```
292
-
293
- ## Related Resources
294
-
295
- - [Action Policy Documentation](https://actionpolicy.evilmartians.io/)
296
- - [Rails Security Guide](https://guides.rubyonrails.org/security.html)