plutonium 0.15.4 → 0.15.6
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/app/assets/plutonium.css +1 -1
- data/app/assets/plutonium.ico +0 -0
- data/app/assets/plutonium.png +0 -0
- data/app/views/components/table_search_input/table_search_input_component.html.erb +3 -3
- data/app/views/resource/_resource_table.html.erb +0 -321
- data/docs/.vitepress/config.ts +61 -0
- data/docs/.vitepress/theme/custom.css +61 -0
- data/docs/.vitepress/theme/index.ts +4 -0
- data/docs/api-examples.md +49 -0
- data/docs/guide/getting-started/authorization.md +296 -0
- data/docs/guide/getting-started/core-concepts.md +432 -0
- data/docs/guide/getting-started/index.md +18 -0
- data/docs/guide/getting-started/installation.md +269 -0
- data/docs/guide/getting-started/resources.md +254 -0
- data/docs/guide/what-is-plutonium.md +211 -0
- data/docs/index.md +43 -0
- data/docs/markdown-examples.md +85 -0
- data/docs/public/android-chrome-192x192.png +0 -0
- data/docs/public/android-chrome-512x512.png +0 -0
- data/docs/public/apple-touch-icon.png +0 -0
- data/docs/public/favicon-16x16.png +0 -0
- data/docs/public/favicon-32x32.png +0 -0
- data/docs/public/favicon.ico +0 -0
- data/docs/public/plutonium.png +0 -0
- data/docs/public/site.webmanifest +1 -0
- data/docs/public/templates/plutonium.rb +21 -0
- data/lib/generators/pu/core/assets/assets_generator.rb +2 -3
- data/lib/generators/pu/core/assets/templates/tailwind.config.js +2 -2
- data/lib/generators/pu/core/install/install_generator.rb +9 -1
- data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +0 -1
- data/lib/plutonium/core/controllers/authorizable.rb +1 -1
- data/lib/plutonium/definition/base.rb +8 -0
- data/lib/plutonium/definition/defineable_props.rb +1 -1
- data/lib/plutonium/definition/presentable.rb +71 -0
- data/lib/plutonium/interaction/README.md +1 -1
- data/lib/plutonium/interaction/base.rb +6 -6
- data/lib/plutonium/lib/deep_freezer.rb +31 -0
- data/lib/plutonium/query/adhoc_block.rb +19 -0
- data/lib/plutonium/query/base.rb +29 -0
- data/lib/plutonium/query/filter.rb +12 -0
- data/lib/plutonium/query/filters/text.rb +77 -0
- data/lib/plutonium/query/model_scope.rb +19 -0
- data/lib/plutonium/railtie.rb +0 -10
- data/lib/plutonium/resource/controller.rb +0 -3
- data/lib/plutonium/resource/controllers/crud_actions/index_action.rb +26 -0
- data/lib/plutonium/resource/controllers/crud_actions.rb +3 -6
- data/lib/plutonium/resource/controllers/defineable.rb +0 -2
- data/lib/plutonium/resource/controllers/queryable.rb +36 -20
- data/lib/plutonium/resource/policy.rb +5 -6
- data/lib/plutonium/resource/query_object.rb +61 -147
- data/lib/plutonium/resource/register.rb +3 -0
- data/lib/plutonium/{refinements/parameter_refinements.rb → support/parameters.rb} +5 -7
- data/lib/plutonium/ui/action_button.rb +34 -19
- data/lib/plutonium/ui/component/methods.rb +1 -1
- data/lib/plutonium/ui/display/resource.rb +19 -15
- data/lib/plutonium/ui/form/query.rb +171 -0
- data/lib/plutonium/ui/form/resource.rb +22 -17
- data/lib/plutonium/ui/table/components/scopes_bar.rb +1 -1
- data/lib/plutonium/ui/table/components/search_bar.rb +6 -139
- data/lib/plutonium/ui/table/resource.rb +10 -9
- data/lib/plutonium/version.rb +1 -1
- data/package-lock.json +5769 -1853
- data/package.json +11 -5
- data/src/js/core.js +0 -1
- data/tailwind.options.js +89 -11
- metadata +37 -13
- data/app/assets/plutonium-original.png +0 -0
- data/app/assets/plutonium-white.png +0 -0
- data/lib/plutonium/interaction/concerns/presentable.rb +0 -73
- data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
- data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
- /data/{templates → docs/public/templates}/base.rb +0 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
# Getting Started with Plutonium
|
2
|
+
|
3
|
+
<!--
|
4
|
+
This guide covers getting up and running with Plutonium.
|
5
|
+
|
6
|
+
After reading this guide, you will know:
|
7
|
+
|
8
|
+
- How to install Plutonium.
|
9
|
+
- The general layout of a Plutonium application.
|
10
|
+
- The basic principles of Resource design.
|
11
|
+
- How to quickly generate the starting pieces of a Plutonium application.
|
12
|
+
-->
|
13
|
+
|
14
|
+
## Prerequisites
|
15
|
+
|
16
|
+
Before using Plutonium, you should be familiar with Rails.
|
17
|
+
Plutonium builds upon many core Rails concepts and conventions.
|
18
|
+
If you're new to Rails or need a refresher, we highly recommend reading the [Rails' guide](https://guides.rubyonrails.org/getting_started.html).
|
@@ -0,0 +1,269 @@
|
|
1
|
+
# Installation and Setup
|
2
|
+
|
3
|
+
::: tip VERSION REQUIREMENTS
|
4
|
+
- Ruby 3.2.2 or higher
|
5
|
+
- Rails 7.1 or higher
|
6
|
+
:::
|
7
|
+
|
8
|
+
## Quick Start
|
9
|
+
|
10
|
+
Get up and running with Plutonium in seconds:
|
11
|
+
|
12
|
+
::: code-group
|
13
|
+
```bash [New App]
|
14
|
+
rails new plutonium_app -a propshaft -j esbuild -c tailwind \
|
15
|
+
-m https://radioactive-labs.github.io/plutonium-core/templates/plutonium.rb
|
16
|
+
```
|
17
|
+
|
18
|
+
```bash [Existing App]
|
19
|
+
bin/rails app:template \
|
20
|
+
LOCATION=https://radioactive-labs.github.io/plutonium-core/templates/base.rb
|
21
|
+
```
|
22
|
+
:::
|
23
|
+
|
24
|
+
## Detailed Installation Guide
|
25
|
+
|
26
|
+
1. Add Plutonium to your Gemfile:
|
27
|
+
|
28
|
+
::: code-group
|
29
|
+
```ruby [Gemfile]
|
30
|
+
gem "plutonium"
|
31
|
+
```
|
32
|
+
|
33
|
+
```bash [Terminal]
|
34
|
+
bundle install
|
35
|
+
```
|
36
|
+
:::
|
37
|
+
|
38
|
+
2. Run the installation generator:
|
39
|
+
|
40
|
+
```bash
|
41
|
+
rails generate pu:core:install
|
42
|
+
```
|
43
|
+
|
44
|
+
This will:
|
45
|
+
- Set up the basic Plutonium structure
|
46
|
+
- Create necessary configuration files
|
47
|
+
- Configure your application for Plutonium
|
48
|
+
|
49
|
+
### Project Structure
|
50
|
+
|
51
|
+
After installation, your project will have the following new directories and files:
|
52
|
+
|
53
|
+
```
|
54
|
+
my_rails_app/
|
55
|
+
├── app/
|
56
|
+
│ ├── controllers/
|
57
|
+
│ │ ├── plutonium_controller.rb # Base controller for Plutonium
|
58
|
+
│ │ └── resource_controller.rb # Base controller for resources
|
59
|
+
│ ├── definitions/
|
60
|
+
│ │ └── resource_definition.rb # Base class for resource definitions
|
61
|
+
│ ├── interactions/
|
62
|
+
│ │ └── resource_interaction.rb # Base class for resource interactions
|
63
|
+
│ ├── models/
|
64
|
+
│ │ └── resource_record.rb # Base module for resource models
|
65
|
+
│ ├── policies/
|
66
|
+
│ │ └── resource_policy.rb # Base class for resource policies
|
67
|
+
│ └── views/
|
68
|
+
│ └── layouts/
|
69
|
+
│ └── resource.html.erb # Base layout for resources
|
70
|
+
├── config/
|
71
|
+
│ ├── initializers/
|
72
|
+
│ │ └── plutonium.rb # Main configuration
|
73
|
+
│ └── packages.rb # Package registration
|
74
|
+
└── packages/ # Directory for modular features
|
75
|
+
└── .keep
|
76
|
+
```
|
77
|
+
|
78
|
+
## Configuration
|
79
|
+
|
80
|
+
### Basic Configuration
|
81
|
+
|
82
|
+
Configure Plutonium in `config/initializers/plutonium.rb`:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
Plutonium.configure do |config|
|
86
|
+
# Load default configuration for version 1.0
|
87
|
+
config.load_defaults 1.0
|
88
|
+
|
89
|
+
# Asset configuration
|
90
|
+
config.assets.stylesheet = "plutonium.css" # Default stylesheet
|
91
|
+
config.assets.script = "plutonium.js" # Default JavaScript
|
92
|
+
config.assets.logo = "plutonium.png" # Default logo
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
### Authentication Setup
|
97
|
+
|
98
|
+
Plutonium supports multiple authentication strategies. Here's how to set up the recommended Rodauth integration:
|
99
|
+
|
100
|
+
1. Install Rodauth:
|
101
|
+
|
102
|
+
```bash
|
103
|
+
rails generate pu:rodauth:install
|
104
|
+
```
|
105
|
+
|
106
|
+
2. Create an authentication account:
|
107
|
+
|
108
|
+
::: code-group
|
109
|
+
```bash [Basic Setup]
|
110
|
+
rails generate pu:rodauth:account user
|
111
|
+
```
|
112
|
+
|
113
|
+
```bash [Custom Setup]
|
114
|
+
# Include selected authentication features
|
115
|
+
rails generate pu:rodauth:account admin --no-defaults \
|
116
|
+
--login --logout --remember --lockout \
|
117
|
+
--create-account --verify-account --close-account \
|
118
|
+
--change-password --reset-password --reset-password-notify \
|
119
|
+
--active-sessions --password-grace-period --otp \
|
120
|
+
--recovery-codes --audit-logging --internal-request
|
121
|
+
```
|
122
|
+
:::
|
123
|
+
|
124
|
+
3. Configure the authentication controller:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
# app/controllers/resource_controller.rb
|
128
|
+
class ResourceController < PlutoniumController
|
129
|
+
include Plutonium::Resource::Controller
|
130
|
+
include Plutonium::Auth::Rodauth(:user)
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
::: tip
|
135
|
+
You can use your existing authentication system by implementing the `current_user` method in `ResourceController`.
|
136
|
+
:::
|
137
|
+
|
138
|
+
<!--
|
139
|
+
## Asset Pipeline Setup
|
140
|
+
|
141
|
+
### JavaScript Setup
|
142
|
+
|
143
|
+
|
144
|
+
Plutonium uses modern JavaScript features. Here's how to set it up:
|
145
|
+
|
146
|
+
1. Install required npm packages:
|
147
|
+
|
148
|
+
::: code-group
|
149
|
+
```bash [importmap]
|
150
|
+
bin/importmap pin @radioactive-labs/plutonium
|
151
|
+
```
|
152
|
+
|
153
|
+
```bash [esbuild]
|
154
|
+
npm install @radioactive-labs/plutonium
|
155
|
+
```
|
156
|
+
:::
|
157
|
+
|
158
|
+
|
159
|
+
2. Configure JavaScript:
|
160
|
+
|
161
|
+
::: code-group
|
162
|
+
```js [app/javascript/controllers/index.js]
|
163
|
+
import { application } from "controllers/application"
|
164
|
+
import { registerControllers } from "@radioactive-labs/plutonium" // [!code ++]
|
165
|
+
registerControllers(application) // [!code ++]
|
166
|
+
```
|
167
|
+
|
168
|
+
```js [app/javascript/application.js]
|
169
|
+
import "@hotwired/turbo-rails"
|
170
|
+
import "controllers"
|
171
|
+
```
|
172
|
+
:::
|
173
|
+
|
174
|
+
### CSS Setup
|
175
|
+
|
176
|
+
Plutonium uses Tailwind CSS. Configure it in your `tailwind.config.js`:
|
177
|
+
|
178
|
+
```js
|
179
|
+
const defaultTheme = require('tailwindcss/defaultTheme')
|
180
|
+
|
181
|
+
module.exports = {
|
182
|
+
content: [
|
183
|
+
'./app/views/**/*.erb',
|
184
|
+
'./app/helpers/**/*.rb',
|
185
|
+
'./app/javascript/**/*.js',
|
186
|
+
'./app/components/**/*.{erb,rb}',
|
187
|
+
'./node_modules/@radioactive-labs/plutonium/**/*.{js,ts}'
|
188
|
+
],
|
189
|
+
theme: {
|
190
|
+
extend: {
|
191
|
+
fontFamily: {
|
192
|
+
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
193
|
+
},
|
194
|
+
},
|
195
|
+
},
|
196
|
+
plugins: [
|
197
|
+
require('@tailwindcss/forms'),
|
198
|
+
require('flowbite/plugin')
|
199
|
+
],
|
200
|
+
}
|
201
|
+
```
|
202
|
+
-->
|
203
|
+
|
204
|
+
## Optional Enhancements
|
205
|
+
|
206
|
+
### Database Performance
|
207
|
+
|
208
|
+
For PostgreSQL/MySQL users, add these recommended gems:
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
group :development, :test do
|
212
|
+
# N+1 query detection
|
213
|
+
gem "prosopite"
|
214
|
+
end
|
215
|
+
|
216
|
+
# Automatic eager loading
|
217
|
+
gem "goldiloader"
|
218
|
+
```
|
219
|
+
|
220
|
+
### Development Tools
|
221
|
+
|
222
|
+
Add helpful development gems:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
# Generate model annotations
|
226
|
+
rails generate pu:gem:annotate
|
227
|
+
|
228
|
+
# Set up environment variables
|
229
|
+
rails generate pu:gem:dotenv
|
230
|
+
```
|
231
|
+
|
232
|
+
<!--
|
233
|
+
## Verification
|
234
|
+
|
235
|
+
Verify your installation:
|
236
|
+
|
237
|
+
```bash
|
238
|
+
# Start your Rails server
|
239
|
+
rails server
|
240
|
+
|
241
|
+
# Check your logs for any warnings or errors
|
242
|
+
tail -f log/development.log
|
243
|
+
|
244
|
+
# Generate and test a sample resource
|
245
|
+
rails generate pu:res:scaffold Post title:string content:text
|
246
|
+
```
|
247
|
+
|
248
|
+
Visit `http://localhost:3000/posts` to verify everything is working.
|
249
|
+
-->
|
250
|
+
|
251
|
+
<!--
|
252
|
+
::: tip Next Steps
|
253
|
+
Now that you have Plutonium installed and configured, you're ready to:
|
254
|
+
1. [Create your first resource](/guide/resources/creating-resources)
|
255
|
+
2. [Set up your first package](/guide/packages/creating-packages)
|
256
|
+
3. [Configure authorization](/guide/authorization/basic-setup)
|
257
|
+
:::
|
258
|
+
-->
|
259
|
+
|
260
|
+
<!--
|
261
|
+
### Getting Help
|
262
|
+
|
263
|
+
If you run into issues:
|
264
|
+
|
265
|
+
1. Check the [FAQ](/guide/faq)
|
266
|
+
2. Search [GitHub Issues](https://github.com/radioactive-labs/plutonium-core/issues)
|
267
|
+
3. Join our [Discord Community](https://discord.gg/plutonium)
|
268
|
+
4. Create a new [GitHub Issue](https://github.com/radioactive-labs/plutonium-core/issues/new)
|
269
|
+
-->
|
@@ -0,0 +1,254 @@
|
|
1
|
+
# Working with Resources
|
2
|
+
|
3
|
+
::: tip What you'll learn
|
4
|
+
- How to create and manage resources in Plutonium
|
5
|
+
- Understanding resource definitions and configurations
|
6
|
+
- Working with fields, associations, and nested resources
|
7
|
+
- Implementing resource policies and scoping
|
8
|
+
- Best practices for resource organization
|
9
|
+
:::
|
10
|
+
|
11
|
+
## Introduction
|
12
|
+
|
13
|
+
Resources are the core building blocks of a Plutonium application. A resource represents a model in your application that can be managed through a consistent interface, complete with views, controllers, and policies.
|
14
|
+
|
15
|
+
## Creating a Resource
|
16
|
+
|
17
|
+
The fastest way to create a resource is using the scaffold generator:
|
18
|
+
|
19
|
+
```bash
|
20
|
+
rails generate pu:res:scaffold Blog user:belongs_to title:string content:text state:string published_at:datetime?
|
21
|
+
```
|
22
|
+
|
23
|
+
This generates several files, including:
|
24
|
+
|
25
|
+
::: code-group
|
26
|
+
```ruby [app/models/blog.rb]
|
27
|
+
class Blog < ResourceRecord
|
28
|
+
belongs_to :user
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
```ruby [app/policies/blog_policy.rb]
|
33
|
+
class BlogPolicy < Plutonium::Resource::Policy
|
34
|
+
def create?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
def read?
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def permitted_attributes_for_create
|
43
|
+
%i[user title content state published_at]
|
44
|
+
end
|
45
|
+
|
46
|
+
def permitted_attributes_for_read
|
47
|
+
%i[user title content state published_at]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
```ruby [app/definitions/blog_definition.rb]
|
53
|
+
class BlogDefinition < Plutonium::Resource::Definition
|
54
|
+
end
|
55
|
+
```
|
56
|
+
:::
|
57
|
+
|
58
|
+
## Resource Definitions
|
59
|
+
|
60
|
+
Resource definitions customize how a resource behaves in your application. They define:
|
61
|
+
- Fields and their types
|
62
|
+
- Available actions
|
63
|
+
- Search and filtering capabilities
|
64
|
+
- Sorting options
|
65
|
+
- Display configurations
|
66
|
+
|
67
|
+
### Basic Field Configuration
|
68
|
+
|
69
|
+
::: code-group
|
70
|
+
```ruby [Simple Fields]
|
71
|
+
class BlogDefinition < Plutonium::Resource::Definition
|
72
|
+
# Basic field definitions
|
73
|
+
field :content, as: :text
|
74
|
+
|
75
|
+
# Field with custom display options
|
76
|
+
field :published_at,
|
77
|
+
as: :datetime,
|
78
|
+
hint: "When this post should be published"
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
```ruby [Custom Displays]
|
83
|
+
class BlogDefinition < Plutonium::Resource::Definition
|
84
|
+
# Customize how fields are displayed
|
85
|
+
display :title, class: "col-span-full"
|
86
|
+
display :content do |f|
|
87
|
+
f.text_tag class: "prose dark:prose-invert"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Custom column display in tables
|
91
|
+
column :state, align: :right
|
92
|
+
end
|
93
|
+
```
|
94
|
+
:::
|
95
|
+
|
96
|
+
<!--
|
97
|
+
### Working with Associations
|
98
|
+
|
99
|
+
Plutonium makes it easy to work with Rails associations:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
class BlogDefinition < Plutonium::Resource::Definition
|
103
|
+
# Define belongs_to association
|
104
|
+
field :user, as: :belongs_to
|
105
|
+
|
106
|
+
# Has-many association with inline creation
|
107
|
+
field :comments do |f|
|
108
|
+
f.has_many_tag nested: true
|
109
|
+
end
|
110
|
+
|
111
|
+
# Configure nested attributes
|
112
|
+
define_nested_input :comments,
|
113
|
+
inputs: %i[content user],
|
114
|
+
limit: 3 do |input|
|
115
|
+
input.define_field_input :content,
|
116
|
+
type: :text,
|
117
|
+
hint: "Keep it constructive"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
-->
|
122
|
+
|
123
|
+
### Adding Custom Actions
|
124
|
+
|
125
|
+
Beyond CRUD, you can add custom actions to your resources:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
# app/interactions/blogs/publish.rb
|
129
|
+
module Blogs
|
130
|
+
class Publish < Plutonium::Resource::Interaction
|
131
|
+
# Define what this interaction accepts
|
132
|
+
attribute :resource, class: Blog
|
133
|
+
attribute :publish_date, :date, default: -> { Time.current }
|
134
|
+
|
135
|
+
presents label: "Publish Blog",
|
136
|
+
icon: Phlex::TablerIcons::Send,
|
137
|
+
description: "Make this blog post public"
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def execute
|
142
|
+
if resource.update(
|
143
|
+
state: "published",
|
144
|
+
published_at: publish_date
|
145
|
+
)
|
146
|
+
succeed(resource)
|
147
|
+
.with_message("Blog post published successfully")
|
148
|
+
.with_redirect_response(resource)
|
149
|
+
else
|
150
|
+
failed(resource.errors)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# app/definitions/blog_definition.rb
|
157
|
+
class BlogDefinition < Plutonium::Resource::Definition
|
158
|
+
# Register the custom action
|
159
|
+
action :publish,
|
160
|
+
interaction: Blogs::Publish,
|
161
|
+
category: :primary
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
### Search and Filtering
|
166
|
+
|
167
|
+
Add search and filtering capabilities to your resources:
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
class BlogDefinition < Plutonium::Resource::Definition
|
171
|
+
# Enable full-text search
|
172
|
+
search do |scope, query|
|
173
|
+
scope.where("title ILIKE ? OR content ILIKE ?",
|
174
|
+
"%#{query}%", "%#{query}%")
|
175
|
+
end
|
176
|
+
|
177
|
+
# Add filters
|
178
|
+
filter :state,
|
179
|
+
with: SelectFilter,
|
180
|
+
choices: %w[draft published]
|
181
|
+
|
182
|
+
filter :published_at,
|
183
|
+
with: DateFilter,
|
184
|
+
predicate: :gteq
|
185
|
+
|
186
|
+
# Add scopes
|
187
|
+
scope :published do |scope|
|
188
|
+
where(state: "published")
|
189
|
+
end
|
190
|
+
scope :draft do |scope|
|
191
|
+
where(state: "draft")
|
192
|
+
end
|
193
|
+
|
194
|
+
# Configure sorting
|
195
|
+
sort :title
|
196
|
+
sort :published_at
|
197
|
+
end
|
198
|
+
```
|
199
|
+
|
200
|
+
## Resource Policies
|
201
|
+
|
202
|
+
Policies control access to your resources:
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
class BlogPolicy < Plutonium::Resource::Policy
|
206
|
+
def permitted_attributes_for_create
|
207
|
+
%i[title content state published_at user_id]
|
208
|
+
end
|
209
|
+
|
210
|
+
def permitted_associations
|
211
|
+
%i[comments]
|
212
|
+
end
|
213
|
+
|
214
|
+
def create?
|
215
|
+
# Allow logged in users to create blogs
|
216
|
+
user.present?
|
217
|
+
end
|
218
|
+
|
219
|
+
def update?
|
220
|
+
# Users can only edit their own blogs
|
221
|
+
record.user_id == user.id
|
222
|
+
end
|
223
|
+
|
224
|
+
def publish?
|
225
|
+
# Only editors can publish
|
226
|
+
user.editor? && record.draft?
|
227
|
+
end
|
228
|
+
|
229
|
+
# Scope visible records
|
230
|
+
relation_scope do |relation|
|
231
|
+
relation = super(relation)
|
232
|
+
next relation unless user.admin?
|
233
|
+
|
234
|
+
relation.with_deleted
|
235
|
+
end
|
236
|
+
end
|
237
|
+
```
|
238
|
+
|
239
|
+
## Best Practices
|
240
|
+
|
241
|
+
::: tip Resource Organization
|
242
|
+
1. Keep resource definitions focused and cohesive
|
243
|
+
2. Use packages to organize related resources
|
244
|
+
3. Leverage policy scopes for authorization
|
245
|
+
4. Extract complex logic into interactions
|
246
|
+
5. Use presenters for view-specific logic
|
247
|
+
:::
|
248
|
+
|
249
|
+
::: warning Common Pitfalls
|
250
|
+
- Avoid putting business logic in definitions
|
251
|
+
- Don't bypass policy checks
|
252
|
+
- Remember to scope resources appropriately
|
253
|
+
- Test your interactions and policies
|
254
|
+
:::
|