plutonium 0.33.1 → 0.34.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/# Plutonium: The pre-alpha demo.md +4 -2
- data/.claude/skills/assets/SKILL.md +416 -0
- data/.claude/skills/connect-resource/SKILL.md +112 -0
- data/.claude/skills/controller/SKILL.md +302 -0
- data/.claude/skills/create-resource/SKILL.md +240 -0
- data/.claude/skills/definition/SKILL.md +218 -0
- data/.claude/skills/definition-actions/SKILL.md +386 -0
- data/.claude/skills/definition-fields/SKILL.md +474 -0
- data/.claude/skills/definition-query/SKILL.md +334 -0
- data/.claude/skills/forms/SKILL.md +439 -0
- data/.claude/skills/installation/SKILL.md +300 -0
- data/.claude/skills/interaction/SKILL.md +382 -0
- data/.claude/skills/model/SKILL.md +267 -0
- data/.claude/skills/model-features/SKILL.md +286 -0
- data/.claude/skills/nested-resources/SKILL.md +274 -0
- data/.claude/skills/package/SKILL.md +191 -0
- data/.claude/skills/policy/SKILL.md +352 -0
- data/.claude/skills/portal/SKILL.md +400 -0
- data/.claude/skills/resource/SKILL.md +281 -0
- data/.claude/skills/rodauth/SKILL.md +452 -0
- data/.claude/skills/views/SKILL.md +563 -0
- data/Appraisals +46 -4
- data/CHANGELOG.md +32 -1
- data/app/assets/plutonium.css +2 -2
- data/config/brakeman.ignore +239 -0
- data/config/initializers/action_policy.rb +1 -1
- data/docs/.vitepress/config.ts +132 -47
- data/docs/concepts/architecture.md +226 -0
- data/docs/concepts/auto-detection.md +254 -0
- data/docs/concepts/index.md +61 -0
- data/docs/concepts/packages-portals.md +304 -0
- data/docs/concepts/resources.md +224 -0
- data/docs/cookbook/blog.md +412 -0
- data/docs/cookbook/index.md +289 -0
- data/docs/cookbook/saas.md +481 -0
- data/docs/getting-started/index.md +56 -0
- data/docs/getting-started/installation.md +146 -0
- data/docs/getting-started/tutorial/01-setup.md +118 -0
- data/docs/getting-started/tutorial/02-first-resource.md +180 -0
- data/docs/getting-started/tutorial/03-authentication.md +246 -0
- data/docs/getting-started/tutorial/04-authorization.md +170 -0
- data/docs/getting-started/tutorial/05-custom-actions.md +202 -0
- data/docs/getting-started/tutorial/06-nested-resources.md +147 -0
- data/docs/getting-started/tutorial/07-customizing-ui.md +254 -0
- data/docs/getting-started/tutorial/index.md +64 -0
- data/docs/guides/adding-resources.md +420 -0
- data/docs/guides/authentication.md +551 -0
- data/docs/guides/authorization.md +468 -0
- data/docs/guides/creating-packages.md +380 -0
- data/docs/guides/custom-actions.md +523 -0
- data/docs/guides/index.md +45 -0
- data/docs/guides/multi-tenancy.md +302 -0
- data/docs/guides/nested-resources.md +411 -0
- data/docs/guides/search-filtering.md +266 -0
- data/docs/guides/theming.md +321 -0
- data/docs/index.md +67 -26
- data/docs/public/CLAUDE.md +64 -21
- data/docs/reference/assets/index.md +496 -0
- data/docs/reference/controller/index.md +363 -0
- data/docs/reference/definition/actions.md +400 -0
- data/docs/reference/definition/fields.md +350 -0
- data/docs/reference/definition/index.md +252 -0
- data/docs/reference/definition/query.md +342 -0
- data/docs/reference/generators/index.md +469 -0
- data/docs/reference/index.md +49 -0
- data/docs/reference/interaction/index.md +445 -0
- data/docs/reference/model/features.md +248 -0
- data/docs/reference/model/index.md +219 -0
- data/docs/reference/policy/index.md +385 -0
- data/docs/reference/portal/index.md +382 -0
- data/docs/reference/views/forms.md +396 -0
- data/docs/reference/views/index.md +479 -0
- data/gemfiles/rails_7.gemfile +9 -2
- data/gemfiles/rails_7.gemfile.lock +146 -111
- data/gemfiles/rails_8.0.gemfile +20 -0
- data/gemfiles/rails_8.0.gemfile.lock +417 -0
- data/gemfiles/rails_8.1.gemfile +20 -0
- data/gemfiles/rails_8.1.gemfile.lock +419 -0
- data/lib/generators/pu/gem/dotenv/templates/.env +2 -0
- data/lib/generators/pu/gem/dotenv/templates/config/initializers/001_ensure_required_env.rb +3 -1
- data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +13 -16
- data/lib/generators/pu/pkg/portal/USAGE +65 -0
- data/lib/generators/pu/pkg/portal/portal_generator.rb +22 -9
- data/lib/generators/pu/res/conn/USAGE +71 -0
- data/lib/generators/pu/res/model/USAGE +106 -110
- data/lib/generators/pu/res/model/templates/model.rb.tt +6 -2
- data/lib/generators/pu/res/scaffold/USAGE +85 -0
- data/lib/generators/pu/rodauth/install_generator.rb +2 -6
- data/lib/generators/pu/rodauth/templates/config/initializers/url_options.rb +17 -0
- data/lib/generators/pu/skills/sync/USAGE +14 -0
- data/lib/generators/pu/skills/sync/sync_generator.rb +66 -0
- data/lib/plutonium/action_policy/sti_policy_lookup.rb +1 -1
- data/lib/plutonium/core/controller.rb +2 -2
- data/lib/plutonium/interaction/base.rb +1 -0
- data/lib/plutonium/package/engine.rb +2 -2
- data/lib/plutonium/query/adhoc_block.rb +6 -2
- data/lib/plutonium/query/model_scope.rb +1 -1
- data/lib/plutonium/railtie.rb +4 -0
- data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +1 -1
- data/lib/plutonium/resource/query_object.rb +38 -8
- data/lib/plutonium/ui/table/components/scopes_bar.rb +39 -34
- data/lib/plutonium/version.rb +1 -1
- data/lib/tasks/release.rake +19 -4
- data/package.json +1 -1
- metadata +76 -39
- data/brakeman.ignore +0 -28
- data/docs/api-examples.md +0 -49
- data/docs/guide/claude-code-guide.md +0 -74
- data/docs/guide/deep-dive/authorization.md +0 -189
- data/docs/guide/deep-dive/multitenancy.md +0 -256
- data/docs/guide/deep-dive/resources.md +0 -390
- data/docs/guide/getting-started/01-installation.md +0 -165
- data/docs/guide/index.md +0 -28
- data/docs/guide/introduction/01-what-is-plutonium.md +0 -211
- data/docs/guide/introduction/02-core-concepts.md +0 -440
- data/docs/guide/tutorial/01-project-setup.md +0 -75
- data/docs/guide/tutorial/02-creating-a-feature-package.md +0 -45
- data/docs/guide/tutorial/03-defining-resources.md +0 -90
- data/docs/guide/tutorial/04-creating-a-portal.md +0 -101
- data/docs/guide/tutorial/05-customizing-the-ui.md +0 -128
- data/docs/guide/tutorial/06-adding-custom-actions.md +0 -101
- data/docs/guide/tutorial/07-implementing-authorization.md +0 -90
- data/docs/markdown-examples.md +0 -85
- data/docs/modules/action.md +0 -244
- data/docs/modules/authentication.md +0 -236
- data/docs/modules/configuration.md +0 -599
- data/docs/modules/controller.md +0 -443
- data/docs/modules/core.md +0 -316
- data/docs/modules/definition.md +0 -1308
- data/docs/modules/display.md +0 -759
- data/docs/modules/form.md +0 -495
- data/docs/modules/generator.md +0 -400
- data/docs/modules/index.md +0 -167
- data/docs/modules/interaction.md +0 -642
- data/docs/modules/package.md +0 -151
- data/docs/modules/policy.md +0 -176
- data/docs/modules/portal.md +0 -710
- data/docs/modules/query.md +0 -297
- data/docs/modules/resource_record.md +0 -618
- data/docs/modules/routing.md +0 -690
- data/docs/modules/table.md +0 -301
- data/docs/modules/ui.md +0 -631
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# Adding Resources
|
|
2
|
+
|
|
3
|
+
This guide covers creating new resources and connecting them to portals.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Generate a resource in the main app
|
|
9
|
+
rails g pu:res:scaffold Product name:string 'price:decimal{10,2}' --dest=main_app
|
|
10
|
+
|
|
11
|
+
# Generate a resource in a feature package
|
|
12
|
+
rails g pu:res:scaffold Product name:string 'price:decimal{10,2}' --dest=inventory
|
|
13
|
+
|
|
14
|
+
# Connect to a portal
|
|
15
|
+
rails g pu:res:conn Product --dest=admin_portal
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## The Resource Generator
|
|
19
|
+
|
|
20
|
+
### Basic Usage
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
rails g pu:res:scaffold ModelName field:type field:type --dest=DESTINATION
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Always specify `--dest`** to avoid interactive prompts:
|
|
27
|
+
- `--dest=main_app` for resources in the main application
|
|
28
|
+
- `--dest=package_name` for resources in a feature package
|
|
29
|
+
|
|
30
|
+
### Field Types
|
|
31
|
+
|
|
32
|
+
Format: `name:type:index_type`
|
|
33
|
+
|
|
34
|
+
| Type | Example | Description |
|
|
35
|
+
|------|---------|-------------|
|
|
36
|
+
| `string` | `title:string` | Short text (required) |
|
|
37
|
+
| `'title:string?'` | `'title:string?'` | Short text (nullable) |
|
|
38
|
+
| `text` | `body:text` | Long text |
|
|
39
|
+
| `integer` | `quantity:integer` | Whole numbers |
|
|
40
|
+
| `decimal` | `'price:decimal{10,2}'` | Decimal with precision |
|
|
41
|
+
| `float` | `rating:float` | Floating point |
|
|
42
|
+
| `boolean` | `active:boolean` | True/false |
|
|
43
|
+
| `date` | `published_on:date` | Date only |
|
|
44
|
+
| `datetime` | `published_at:datetime` | Date and time |
|
|
45
|
+
| `time` | `starts_at:time` | Time only |
|
|
46
|
+
| `json` | `metadata:json` | JSON data |
|
|
47
|
+
|
|
48
|
+
### Nullable Fields
|
|
49
|
+
|
|
50
|
+
Append `?` to make a field nullable. **Quote fields with special characters**:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
'name:string?' # Nullable string
|
|
54
|
+
'description:text?' # Nullable text
|
|
55
|
+
'published_at:datetime?' # Nullable datetime
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Decimal Precision
|
|
59
|
+
|
|
60
|
+
Use `{precision,scale}` syntax for decimal fields:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
'price:decimal{10,2}' # precision: 10, scale: 2
|
|
64
|
+
'latitude:decimal{11,8}' # precision: 11, scale: 8
|
|
65
|
+
'amount:decimal?{15,2}' # nullable with precision
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Associations
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Required belongs_to
|
|
72
|
+
user:belongs_to
|
|
73
|
+
company:references # Same as belongs_to
|
|
74
|
+
|
|
75
|
+
# Nullable belongs_to
|
|
76
|
+
'parent:belongs_to?' # Creates: null: true, optional: true
|
|
77
|
+
|
|
78
|
+
# Cross-package reference
|
|
79
|
+
blogging/post:belongs_to
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Indexes
|
|
83
|
+
|
|
84
|
+
Add index type as the third segment:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
email:string:index # Regular index
|
|
88
|
+
email:string:uniq # Unique index
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Special Types
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
password_digest # has_secure_password
|
|
95
|
+
auth_token:token # has_secure_token (auto unique index)
|
|
96
|
+
content:rich_text # has_rich_text (Action Text)
|
|
97
|
+
avatar:attachment # has_one_attached (Active Storage)
|
|
98
|
+
photos:attachments # has_many_attached
|
|
99
|
+
price_cents:integer # has_cents (money field)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Generator Options
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Skip model generation (use existing model)
|
|
106
|
+
rails g pu:res:scaffold Post --no-model --dest=main_app
|
|
107
|
+
|
|
108
|
+
# Skip migration generation
|
|
109
|
+
rails g pu:res:scaffold Post --no-migration --dest=main_app
|
|
110
|
+
|
|
111
|
+
# Both (for existing models with Plutonium::Resource::Record)
|
|
112
|
+
rails g pu:res:scaffold Post --no-model --no-migration --dest=main_app
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Generated Files
|
|
116
|
+
|
|
117
|
+
### For Main App Resources
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
app/
|
|
121
|
+
├── models/post.rb
|
|
122
|
+
├── controllers/posts_controller.rb
|
|
123
|
+
├── definitions/post_definition.rb
|
|
124
|
+
└── policies/post_policy.rb
|
|
125
|
+
db/migrate/xxx_create_posts.rb
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### For Packaged Resources
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
packages/blogging/
|
|
132
|
+
├── app/
|
|
133
|
+
│ ├── models/blogging/post.rb
|
|
134
|
+
│ ├── controllers/blogging/posts_controller.rb
|
|
135
|
+
│ ├── definitions/blogging/post_definition.rb
|
|
136
|
+
│ └── policies/blogging/post_policy.rb
|
|
137
|
+
db/migrate/xxx_create_blogging_posts.rb
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Model
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
class Post < ResourceRecord
|
|
144
|
+
include Plutonium::Resource::Record
|
|
145
|
+
end
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Definition
|
|
149
|
+
|
|
150
|
+
```ruby
|
|
151
|
+
class PostDefinition < ResourceDefinition
|
|
152
|
+
# Fields auto-detected from model
|
|
153
|
+
end
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Policy
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
class PostPolicy < ResourcePolicy
|
|
160
|
+
def permitted_attributes_for_create
|
|
161
|
+
%i[title content user_id]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def permitted_attributes_for_read
|
|
165
|
+
%i[title content user_id created_at updated_at]
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Connecting to Portals
|
|
171
|
+
|
|
172
|
+
Resources must be connected to a portal to be accessible via the web.
|
|
173
|
+
|
|
174
|
+
### Using the Generator
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
rails g pu:res:conn Post --dest=admin_portal
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
This:
|
|
181
|
+
1. Registers the resource in portal routes
|
|
182
|
+
2. Creates a portal-specific controller
|
|
183
|
+
3. Creates portal-specific policy and definition (if base versions don't exist)
|
|
184
|
+
|
|
185
|
+
### Connecting Multiple Resources
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
rails g pu:res:conn Post Comment Tag --dest=admin_portal
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Connecting Namespaced Resources
|
|
192
|
+
|
|
193
|
+
Use the full class name for packaged resources:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
rails g pu:res:conn Blogging::Post Blogging::Comment --dest=admin_portal
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### What Gets Generated
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
packages/admin_portal/
|
|
203
|
+
├── app/
|
|
204
|
+
│ ├── controllers/admin_portal/posts_controller.rb
|
|
205
|
+
│ ├── policies/admin_portal/post_policy.rb
|
|
206
|
+
│ └── definitions/admin_portal/post_definition.rb
|
|
207
|
+
└── config/routes.rb # Updated with register_resource
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Portal-Specific Customization
|
|
211
|
+
|
|
212
|
+
### Portal Controller
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
# packages/admin_portal/app/controllers/admin_portal/posts_controller.rb
|
|
216
|
+
class AdminPortal::PostsController < ::PostsController
|
|
217
|
+
include AdminPortal::Concerns::Controller
|
|
218
|
+
|
|
219
|
+
private
|
|
220
|
+
|
|
221
|
+
def build_resource
|
|
222
|
+
super.tap do |post|
|
|
223
|
+
post.user = current_user
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Portal Definition
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
# packages/admin_portal/app/definitions/admin_portal/post_definition.rb
|
|
233
|
+
class AdminPortal::PostDefinition < ::PostDefinition
|
|
234
|
+
# Add admin-only fields
|
|
235
|
+
field :internal_notes
|
|
236
|
+
|
|
237
|
+
# Customize existing fields
|
|
238
|
+
field :status, as: :select, collection: %w[draft published archived]
|
|
239
|
+
end
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Portal Policy
|
|
243
|
+
|
|
244
|
+
```ruby
|
|
245
|
+
# packages/admin_portal/app/policies/admin_portal/post_policy.rb
|
|
246
|
+
class AdminPortal::PostPolicy < ::PostPolicy
|
|
247
|
+
include AdminPortal::ResourcePolicy
|
|
248
|
+
|
|
249
|
+
# Admins can do everything
|
|
250
|
+
def destroy?
|
|
251
|
+
true
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def permitted_attributes_for_create
|
|
255
|
+
super + [:internal_notes]
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Multiple Portals
|
|
261
|
+
|
|
262
|
+
Connect the same resource to multiple portals:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
rails g pu:res:conn Post --dest=admin_portal
|
|
266
|
+
rails g pu:res:conn Post --dest=author_portal
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Each portal can have different customizations.
|
|
270
|
+
|
|
271
|
+
## From Existing Models
|
|
272
|
+
|
|
273
|
+
If you have existing Rails models you want to convert to Plutonium resources:
|
|
274
|
+
|
|
275
|
+
### Option 1: Model already includes Plutonium::Resource::Record
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
rails g pu:res:scaffold Post --no-model --no-migration --dest=main_app
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
This generates only the definition, policy, and controller.
|
|
282
|
+
|
|
283
|
+
### Option 2: Let the generator update the model
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
rails g pu:res:scaffold Post --dest=main_app
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Run without attributes to auto-import fields from the model's content columns.
|
|
290
|
+
|
|
291
|
+
### Required Model Setup
|
|
292
|
+
|
|
293
|
+
Your model must include `Plutonium::Resource::Record`:
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
class Post < ApplicationRecord
|
|
297
|
+
include Plutonium::Resource::Record
|
|
298
|
+
end
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Adding Fields After Creation
|
|
302
|
+
|
|
303
|
+
### 1. Create Migration
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
rails g migration AddStatusToPosts status:string
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### 2. Update Model (if needed)
|
|
310
|
+
|
|
311
|
+
```ruby
|
|
312
|
+
class Post < ResourceRecord
|
|
313
|
+
validates :status, inclusion: { in: %w[draft published] }
|
|
314
|
+
end
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 3. Fields Auto-Detected
|
|
318
|
+
|
|
319
|
+
New columns automatically appear in forms. To customize:
|
|
320
|
+
|
|
321
|
+
```ruby
|
|
322
|
+
# In definition
|
|
323
|
+
field :status, as: :select, collection: %w[draft published]
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Migration Customizations
|
|
327
|
+
|
|
328
|
+
Always review and customize generated migrations:
|
|
329
|
+
|
|
330
|
+
### Inline Indexes (preferred)
|
|
331
|
+
|
|
332
|
+
```ruby
|
|
333
|
+
create_table :posts do |t|
|
|
334
|
+
t.belongs_to :user, null: false, foreign_key: true
|
|
335
|
+
t.string :title, null: false
|
|
336
|
+
|
|
337
|
+
t.timestamps
|
|
338
|
+
|
|
339
|
+
t.index :title
|
|
340
|
+
t.index [:user_id, :title], unique: true
|
|
341
|
+
end
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Cascade Delete
|
|
345
|
+
|
|
346
|
+
```ruby
|
|
347
|
+
t.belongs_to :user, null: false, foreign_key: {on_delete: :cascade}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Default Values
|
|
351
|
+
|
|
352
|
+
```ruby
|
|
353
|
+
t.boolean :is_active, default: true
|
|
354
|
+
t.integer :status, default: 0
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Removing Resources
|
|
358
|
+
|
|
359
|
+
### Remove from Portal
|
|
360
|
+
|
|
361
|
+
1. Remove `register_resource` from portal routes
|
|
362
|
+
2. Delete portal-specific files in `packages/portal_name/app/`
|
|
363
|
+
|
|
364
|
+
### Remove Entirely
|
|
365
|
+
|
|
366
|
+
```bash
|
|
367
|
+
# Remove files (main app example)
|
|
368
|
+
rm app/models/post.rb
|
|
369
|
+
rm app/controllers/posts_controller.rb
|
|
370
|
+
rm app/definitions/post_definition.rb
|
|
371
|
+
rm app/policies/post_policy.rb
|
|
372
|
+
|
|
373
|
+
# Create migration to drop table
|
|
374
|
+
rails g migration DropPosts
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
## Best Practices
|
|
378
|
+
|
|
379
|
+
### 1. Always Specify `--dest`
|
|
380
|
+
Avoids interactive prompts and makes commands reproducible.
|
|
381
|
+
|
|
382
|
+
### 2. Quote Special Characters
|
|
383
|
+
Fields with `?` or `{}` must be quoted to prevent shell expansion:
|
|
384
|
+
```bash
|
|
385
|
+
rails g pu:res:scaffold Post 'content:text?' 'price:decimal{10,2}' --dest=main_app
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### 3. Run Migrations Before Connecting
|
|
389
|
+
```bash
|
|
390
|
+
rails g pu:res:scaffold Post title:string --dest=main_app
|
|
391
|
+
rails db:migrate
|
|
392
|
+
rails g pu:res:conn Post --dest=admin_portal
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### 4. Review Generated Migrations
|
|
396
|
+
Add cascade deletes, composite indexes, and default values as needed.
|
|
397
|
+
|
|
398
|
+
## Troubleshooting
|
|
399
|
+
|
|
400
|
+
### Resource Not Found
|
|
401
|
+
|
|
402
|
+
Ensure the resource is connected to the portal with `register_resource`.
|
|
403
|
+
|
|
404
|
+
### Fields Not Showing
|
|
405
|
+
|
|
406
|
+
Check that the migration has run and the policy includes the field in `permitted_attributes_for_read`.
|
|
407
|
+
|
|
408
|
+
### Policy Denying Access
|
|
409
|
+
|
|
410
|
+
Check the policy's permission methods (`index?`, `show?`, `create?`, etc.) return `true`.
|
|
411
|
+
|
|
412
|
+
### Connection Generator Fails
|
|
413
|
+
|
|
414
|
+
Ensure migrations have run - the generator reads model columns to build policy attributes.
|
|
415
|
+
|
|
416
|
+
## Related
|
|
417
|
+
|
|
418
|
+
- [Creating Packages](./creating-packages)
|
|
419
|
+
- [Nested Resources](./nested-resources)
|
|
420
|
+
- [Custom Actions](./custom-actions)
|