claude-agent-framework 1.0.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.
- package/README.md +128 -0
- package/bin/claude-framework +3 -0
- package/framework/agents/design-lead.md +240 -0
- package/framework/agents/product-owner.md +179 -0
- package/framework/agents/tech-lead.md +226 -0
- package/framework/commands/ayuda.md +127 -0
- package/framework/commands/a/303/261adir.md +98 -0
- package/framework/commands/backup.md +397 -0
- package/framework/commands/cambiar.md +110 -0
- package/framework/commands/cloud.md +457 -0
- package/framework/commands/code.md +142 -0
- package/framework/commands/debug.md +334 -0
- package/framework/commands/deploy.md +383 -0
- package/framework/commands/deshacer.md +120 -0
- package/framework/commands/estado.md +218 -0
- package/framework/commands/explica.md +227 -0
- package/framework/commands/feature.md +120 -0
- package/framework/commands/git.md +427 -0
- package/framework/commands/historial.md +202 -0
- package/framework/commands/learn.md +408 -0
- package/framework/commands/movil.md +245 -0
- package/framework/commands/nuevo.md +118 -0
- package/framework/commands/plan.md +134 -0
- package/framework/commands/prd.md +113 -0
- package/framework/commands/probar.md +148 -0
- package/framework/commands/revisar.md +208 -0
- package/framework/commands/seeds.md +230 -0
- package/framework/commands/seguridad.md +226 -0
- package/framework/commands/tasks.md +157 -0
- package/framework/skills/architecture/algorithms.md +970 -0
- package/framework/skills/architecture/clean-code.md +1080 -0
- package/framework/skills/architecture/design-patterns.md +1984 -0
- package/framework/skills/architecture/functional-programming.md +972 -0
- package/framework/skills/architecture/solid.md +991 -0
- package/framework/skills/cloud/cloud-aws.md +848 -0
- package/framework/skills/cloud/cloud-azure.md +931 -0
- package/framework/skills/cloud/cloud-gcp.md +848 -0
- package/framework/skills/cloud/message-queues.md +1229 -0
- package/framework/skills/core/accessibility.md +401 -0
- package/framework/skills/core/api.md +474 -0
- package/framework/skills/core/authentication.md +306 -0
- package/framework/skills/core/authorization.md +388 -0
- package/framework/skills/core/background-jobs.md +341 -0
- package/framework/skills/core/caching.md +473 -0
- package/framework/skills/core/code-review.md +341 -0
- package/framework/skills/core/controllers.md +290 -0
- package/framework/skills/core/cua.md +285 -0
- package/framework/skills/core/documentation.md +472 -0
- package/framework/skills/core/file-uploads.md +351 -0
- package/framework/skills/core/hotwire-native.md +296 -0
- package/framework/skills/core/hotwire.md +278 -0
- package/framework/skills/core/i18n.md +334 -0
- package/framework/skills/core/imports-exports.md +750 -0
- package/framework/skills/core/infrastructure.md +337 -0
- package/framework/skills/core/models.md +228 -0
- package/framework/skills/core/notifications.md +672 -0
- package/framework/skills/core/payments.md +581 -0
- package/framework/skills/core/performance.md +361 -0
- package/framework/skills/core/rails-scaffold.md +131 -0
- package/framework/skills/core/search.md +518 -0
- package/framework/skills/core/security.md +565 -0
- package/framework/skills/core/seeds.md +307 -0
- package/framework/skills/core/seo.md +542 -0
- package/framework/skills/core/testing.md +393 -0
- package/framework/skills/core/views.md +260 -0
- package/framework/skills/core/websockets.md +564 -0
- package/framework/skills/data/advanced-sql.md +1204 -0
- package/framework/skills/data/nosql.md +1141 -0
- package/framework/skills/devops/containers-advanced.md +1237 -0
- package/framework/skills/devops/debugging.md +834 -0
- package/framework/skills/devops/git-workflow.md +752 -0
- package/framework/skills/devops/networking.md +932 -0
- package/framework/skills/devops/shell-scripting.md +1132 -0
- package/framework/sub-agents/architecture-patterns-agent.md +1450 -0
- package/framework/sub-agents/cloud-agent.md +677 -0
- package/framework/sub-agents/data.md +504 -0
- package/framework/sub-agents/debugging-agent.md +554 -0
- package/framework/sub-agents/devops.md +483 -0
- package/framework/sub-agents/docs.md +176 -0
- package/framework/sub-agents/frontend-dev.md +349 -0
- package/framework/sub-agents/git-workflow-agent.md +697 -0
- package/framework/sub-agents/integrations.md +630 -0
- package/framework/sub-agents/native-dev.md +434 -0
- package/framework/sub-agents/qa.md +138 -0
- package/framework/sub-agents/rails-dev.md +375 -0
- package/framework/sub-agents/security.md +526 -0
- package/framework/sub-agents/ui.md +437 -0
- package/framework/sub-agents/ux.md +284 -0
- package/framework/templates/api-spec.md +500 -0
- package/framework/templates/component-spec.md +248 -0
- package/framework/templates/feature.json +13 -0
- package/framework/templates/model-spec.md +318 -0
- package/framework/templates/prd-template.md +80 -0
- package/framework/templates/task-plan.md +122 -0
- package/framework/templates/task-user-story.md +52 -0
- package/framework/templates/technical-spec.md +260 -0
- package/framework/templates/user-story.md +95 -0
- package/package.json +42 -0
- package/project-templates/CLAUDE.md +42 -0
- package/project-templates/contexts/architecture.md +25 -0
- package/project-templates/contexts/conventions.md +46 -0
- package/project-templates/contexts/design-system.md +47 -0
- package/project-templates/contexts/requirements.md +38 -0
- package/project-templates/contexts/stack.md +30 -0
- package/project-templates/history/active/models.md +11 -0
- package/project-templates/history/changelog.md +15 -0
- package/project-templates/workspace/.gitkeep +0 -0
- package/src/cli.js +52 -0
- package/src/init.js +104 -0
- package/src/status.js +75 -0
- package/src/update.js +88 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Skill: Performance
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Optimize Rails application performance through database queries, caching, and efficient code.
|
|
5
|
+
|
|
6
|
+
## Database Optimization
|
|
7
|
+
|
|
8
|
+
### N+1 Query Prevention
|
|
9
|
+
|
|
10
|
+
```ruby
|
|
11
|
+
# BAD - N+1 queries
|
|
12
|
+
@articles = Article.all
|
|
13
|
+
@articles.each do |article|
|
|
14
|
+
puts article.user.name # New query for each article
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# GOOD - Eager loading
|
|
18
|
+
@articles = Article.includes(:user)
|
|
19
|
+
@articles.each do |article|
|
|
20
|
+
puts article.user.name # No additional queries
|
|
21
|
+
end
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Eager Loading Methods
|
|
25
|
+
```ruby
|
|
26
|
+
# includes - Separate queries, smart loading
|
|
27
|
+
Article.includes(:user, :comments)
|
|
28
|
+
|
|
29
|
+
# preload - Always separate queries
|
|
30
|
+
Article.preload(:user)
|
|
31
|
+
|
|
32
|
+
# eager_load - Single LEFT OUTER JOIN
|
|
33
|
+
Article.eager_load(:user)
|
|
34
|
+
|
|
35
|
+
# Nested associations
|
|
36
|
+
Article.includes(comments: :user)
|
|
37
|
+
Article.includes(:user, comments: [:user, :likes])
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Bullet Gem (Development)
|
|
41
|
+
```ruby
|
|
42
|
+
# Gemfile
|
|
43
|
+
group :development do
|
|
44
|
+
gem "bullet"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# config/environments/development.rb
|
|
48
|
+
config.after_initialize do
|
|
49
|
+
Bullet.enable = true
|
|
50
|
+
Bullet.alert = true
|
|
51
|
+
Bullet.bullet_logger = true
|
|
52
|
+
Bullet.rails_logger = true
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Select Only Needed Columns
|
|
57
|
+
```ruby
|
|
58
|
+
# BAD - Loads all columns
|
|
59
|
+
User.all.map(&:name)
|
|
60
|
+
|
|
61
|
+
# GOOD - Only loads name
|
|
62
|
+
User.pluck(:name)
|
|
63
|
+
|
|
64
|
+
# GOOD - Select specific columns
|
|
65
|
+
User.select(:id, :name, :email)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Batch Processing
|
|
69
|
+
```ruby
|
|
70
|
+
# BAD - Loads all records into memory
|
|
71
|
+
User.all.each { |user| process(user) }
|
|
72
|
+
|
|
73
|
+
# GOOD - Loads in batches of 1000
|
|
74
|
+
User.find_each { |user| process(user) }
|
|
75
|
+
|
|
76
|
+
# Custom batch size
|
|
77
|
+
User.find_each(batch_size: 500) { |user| process(user) }
|
|
78
|
+
|
|
79
|
+
# With batches
|
|
80
|
+
User.in_batches(of: 1000) do |batch|
|
|
81
|
+
batch.update_all(processed: true)
|
|
82
|
+
end
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Database Indexes
|
|
86
|
+
```ruby
|
|
87
|
+
# Migration with indexes
|
|
88
|
+
class CreateArticles < ActiveRecord::Migration[8.0]
|
|
89
|
+
def change
|
|
90
|
+
create_table :articles do |t|
|
|
91
|
+
t.string :title, null: false
|
|
92
|
+
t.references :user, null: false, foreign_key: true
|
|
93
|
+
t.boolean :published, default: false
|
|
94
|
+
t.datetime :published_at
|
|
95
|
+
t.timestamps
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Single column indexes
|
|
99
|
+
add_index :articles, :published
|
|
100
|
+
add_index :articles, :published_at
|
|
101
|
+
|
|
102
|
+
# Composite index (order matters!)
|
|
103
|
+
add_index :articles, [:user_id, :published]
|
|
104
|
+
|
|
105
|
+
# Unique index
|
|
106
|
+
add_index :articles, :slug, unique: true
|
|
107
|
+
|
|
108
|
+
# Partial index
|
|
109
|
+
add_index :articles, :published_at, where: "published = true"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Query Optimization
|
|
115
|
+
```ruby
|
|
116
|
+
# Use exists? instead of present?
|
|
117
|
+
User.where(admin: true).exists? # SELECT 1 ... LIMIT 1
|
|
118
|
+
User.where(admin: true).present? # SELECT * ... (loads all)
|
|
119
|
+
|
|
120
|
+
# Use count vs size vs length
|
|
121
|
+
relation.count # Always SQL COUNT
|
|
122
|
+
relation.size # COUNT if not loaded, length if loaded
|
|
123
|
+
relation.length # Always loads records, then counts
|
|
124
|
+
|
|
125
|
+
# Use find_by instead of where.first
|
|
126
|
+
User.find_by(email: "test@example.com") # Optimized
|
|
127
|
+
User.where(email: "test@example.com").first # Less optimal
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Caching
|
|
131
|
+
|
|
132
|
+
### Fragment Caching
|
|
133
|
+
```erb
|
|
134
|
+
<%# app/views/articles/index.html.erb %>
|
|
135
|
+
<% @articles.each do |article| %>
|
|
136
|
+
<%= cache article do %>
|
|
137
|
+
<%= render article %>
|
|
138
|
+
<% end %>
|
|
139
|
+
<% end %>
|
|
140
|
+
|
|
141
|
+
<%# With explicit key %>
|
|
142
|
+
<%= cache ["v1", article, current_user.admin?] do %>
|
|
143
|
+
<%= render article %>
|
|
144
|
+
<% end %>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Collection Caching
|
|
148
|
+
```erb
|
|
149
|
+
<%# Cached collection rendering %>
|
|
150
|
+
<%= render partial: "article", collection: @articles, cached: true %>
|
|
151
|
+
|
|
152
|
+
<%# With cache key prefix %>
|
|
153
|
+
<%= render partial: "article",
|
|
154
|
+
collection: @articles,
|
|
155
|
+
cached: ->(article) { ["v2", article] } %>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Russian Doll Caching
|
|
159
|
+
```erb
|
|
160
|
+
<%# Parent caches children %>
|
|
161
|
+
<%= cache @article do %>
|
|
162
|
+
<h1><%= @article.title %></h1>
|
|
163
|
+
|
|
164
|
+
<% @article.comments.each do |comment| %>
|
|
165
|
+
<%= cache comment do %>
|
|
166
|
+
<%= render comment %>
|
|
167
|
+
<% end %>
|
|
168
|
+
<% end %>
|
|
169
|
+
<% end %>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Low-Level Caching
|
|
173
|
+
```ruby
|
|
174
|
+
class Article < ApplicationRecord
|
|
175
|
+
def expensive_calculation
|
|
176
|
+
Rails.cache.fetch("article/#{id}/calculation", expires_in: 1.hour) do
|
|
177
|
+
# Expensive operation
|
|
178
|
+
perform_complex_calculation
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Manual cache operations
|
|
184
|
+
Rails.cache.write("key", value, expires_in: 1.hour)
|
|
185
|
+
Rails.cache.read("key")
|
|
186
|
+
Rails.cache.delete("key")
|
|
187
|
+
Rails.cache.exist?("key")
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Counter Caches
|
|
191
|
+
```ruby
|
|
192
|
+
# Migration
|
|
193
|
+
class AddCommentsCountToArticles < ActiveRecord::Migration[8.0]
|
|
194
|
+
def change
|
|
195
|
+
add_column :articles, :comments_count, :integer, default: 0, null: false
|
|
196
|
+
|
|
197
|
+
# Populate existing counts
|
|
198
|
+
Article.find_each do |article|
|
|
199
|
+
Article.reset_counters(article.id, :comments)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Model
|
|
205
|
+
class Comment < ApplicationRecord
|
|
206
|
+
belongs_to :article, counter_cache: true
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Usage - no query needed!
|
|
210
|
+
@article.comments_count
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## View Performance
|
|
214
|
+
|
|
215
|
+
### Turbo Frames for Partial Updates
|
|
216
|
+
```erb
|
|
217
|
+
<%# Only update what changed %>
|
|
218
|
+
<%= turbo_frame_tag "article_#{@article.id}" do %>
|
|
219
|
+
<%= render @article %>
|
|
220
|
+
<% end %>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Lazy Loading
|
|
224
|
+
```erb
|
|
225
|
+
<%# Load comments only when scrolled to %>
|
|
226
|
+
<%= turbo_frame_tag "comments",
|
|
227
|
+
src: article_comments_path(@article),
|
|
228
|
+
loading: :lazy do %>
|
|
229
|
+
<p>Loading comments...</p>
|
|
230
|
+
<% end %>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Pagination
|
|
234
|
+
```ruby
|
|
235
|
+
# Controller with Pagy
|
|
236
|
+
class ArticlesController < ApplicationController
|
|
237
|
+
include Pagy::Backend
|
|
238
|
+
|
|
239
|
+
def index
|
|
240
|
+
@pagy, @articles = pagy(Article.published.recent, items: 20)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```erb
|
|
246
|
+
<%# View %>
|
|
247
|
+
<%= render @articles %>
|
|
248
|
+
<%== pagy_nav(@pagy) %>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Asset Optimization
|
|
252
|
+
```ruby
|
|
253
|
+
# config/environments/production.rb
|
|
254
|
+
config.assets.css_compressor = :sass
|
|
255
|
+
config.assets.js_compressor = :terser
|
|
256
|
+
|
|
257
|
+
# Use CDN
|
|
258
|
+
config.asset_host = "https://cdn.example.com"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Background Processing
|
|
262
|
+
|
|
263
|
+
### Move Slow Operations to Jobs
|
|
264
|
+
```ruby
|
|
265
|
+
# BAD - Blocks request
|
|
266
|
+
def create
|
|
267
|
+
@article = Article.create!(article_params)
|
|
268
|
+
ArticleMailer.published(@article).deliver_now
|
|
269
|
+
SearchIndex.update(@article)
|
|
270
|
+
Analytics.track("article_created", @article.id)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# GOOD - Process async
|
|
274
|
+
def create
|
|
275
|
+
@article = Article.create!(article_params)
|
|
276
|
+
ArticlePublishedJob.perform_later(@article.id)
|
|
277
|
+
end
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Memory Optimization
|
|
281
|
+
|
|
282
|
+
### Avoid Loading Large Datasets
|
|
283
|
+
```ruby
|
|
284
|
+
# BAD - Loads all into memory
|
|
285
|
+
csv_data = Article.all.map do |a|
|
|
286
|
+
[a.id, a.title, a.user.name]
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# GOOD - Stream processing
|
|
290
|
+
def generate_csv
|
|
291
|
+
Enumerator.new do |yielder|
|
|
292
|
+
yielder << CSV.generate_line(["ID", "Title", "Author"])
|
|
293
|
+
|
|
294
|
+
Article.includes(:user).find_each do |article|
|
|
295
|
+
yielder << CSV.generate_line([article.id, article.title, article.user.name])
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Pluck vs Map
|
|
302
|
+
```ruby
|
|
303
|
+
# BAD - Instantiates all AR objects
|
|
304
|
+
User.all.map(&:email)
|
|
305
|
+
|
|
306
|
+
# GOOD - Returns array of values
|
|
307
|
+
User.pluck(:email)
|
|
308
|
+
|
|
309
|
+
# Multiple columns
|
|
310
|
+
User.pluck(:id, :email, :name)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Monitoring
|
|
314
|
+
|
|
315
|
+
### Request Logging
|
|
316
|
+
```ruby
|
|
317
|
+
# config/environments/production.rb
|
|
318
|
+
config.log_level = :info
|
|
319
|
+
config.log_tags = [:request_id]
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Rack Mini Profiler (Development)
|
|
323
|
+
```ruby
|
|
324
|
+
# Gemfile
|
|
325
|
+
gem "rack-mini-profiler"
|
|
326
|
+
|
|
327
|
+
# Access at /?pp=help for options
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Performance Testing
|
|
331
|
+
```ruby
|
|
332
|
+
# spec/performance/articles_spec.rb
|
|
333
|
+
require "rails_helper"
|
|
334
|
+
require "benchmark"
|
|
335
|
+
|
|
336
|
+
RSpec.describe "Article performance", type: :request do
|
|
337
|
+
let!(:articles) { create_list(:article, 100, :with_comments) }
|
|
338
|
+
|
|
339
|
+
it "loads index quickly" do
|
|
340
|
+
time = Benchmark.measure { get articles_path }
|
|
341
|
+
expect(time.real).to be < 0.5
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
it "avoids N+1 queries" do
|
|
345
|
+
expect {
|
|
346
|
+
get articles_path
|
|
347
|
+
}.to make_database_queries(count: 0..5)
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Checklist
|
|
353
|
+
|
|
354
|
+
- [ ] No N+1 queries (use Bullet in development)
|
|
355
|
+
- [ ] Proper database indexes for queries
|
|
356
|
+
- [ ] Fragment caching for expensive views
|
|
357
|
+
- [ ] Counter caches for counts
|
|
358
|
+
- [ ] Pagination for lists
|
|
359
|
+
- [ ] Background jobs for slow operations
|
|
360
|
+
- [ ] Batch processing for large datasets
|
|
361
|
+
- [ ] Select only needed columns
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Skill: Rails Scaffold
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Generate complete Rails resources with models, controllers, views, and routes following Rails conventions.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
- Creating new resources/entities
|
|
8
|
+
- Setting up CRUD operations
|
|
9
|
+
- Initial feature scaffolding
|
|
10
|
+
|
|
11
|
+
## Implementation
|
|
12
|
+
|
|
13
|
+
### Standard Scaffold Command
|
|
14
|
+
```bash
|
|
15
|
+
rails generate scaffold ResourceName field:type field:type --skip-jbuilder
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Common Field Types
|
|
19
|
+
```
|
|
20
|
+
string - Short text (name, title)
|
|
21
|
+
text - Long text (description, content)
|
|
22
|
+
integer - Whole numbers
|
|
23
|
+
decimal - Money, precise numbers
|
|
24
|
+
float - Scientific numbers
|
|
25
|
+
boolean - True/false
|
|
26
|
+
date - Date only
|
|
27
|
+
datetime - Date and time
|
|
28
|
+
time - Time only
|
|
29
|
+
references - Foreign key (belongs_to)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Example: Complete Resource
|
|
33
|
+
```bash
|
|
34
|
+
# Generate scaffold
|
|
35
|
+
rails generate scaffold Article title:string body:text published:boolean user:references --skip-jbuilder
|
|
36
|
+
|
|
37
|
+
# Run migration
|
|
38
|
+
rails db:migrate
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Generated Files
|
|
42
|
+
```
|
|
43
|
+
app/models/article.rb
|
|
44
|
+
app/controllers/articles_controller.rb
|
|
45
|
+
app/views/articles/
|
|
46
|
+
├── _article.html.erb
|
|
47
|
+
├── _form.html.erb
|
|
48
|
+
├── edit.html.erb
|
|
49
|
+
├── index.html.erb
|
|
50
|
+
├── new.html.erb
|
|
51
|
+
└── show.html.erb
|
|
52
|
+
db/migrate/TIMESTAMP_create_articles.rb
|
|
53
|
+
config/routes.rb (modified)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Post-Scaffold Checklist
|
|
57
|
+
|
|
58
|
+
### 1. Model Enhancements
|
|
59
|
+
```ruby
|
|
60
|
+
class Article < ApplicationRecord
|
|
61
|
+
# Associations
|
|
62
|
+
belongs_to :user
|
|
63
|
+
has_many :comments, dependent: :destroy
|
|
64
|
+
|
|
65
|
+
# Validations
|
|
66
|
+
validates :title, presence: true, length: { maximum: 255 }
|
|
67
|
+
validates :body, presence: true
|
|
68
|
+
|
|
69
|
+
# Scopes
|
|
70
|
+
scope :published, -> { where(published: true) }
|
|
71
|
+
scope :recent, -> { order(created_at: :desc) }
|
|
72
|
+
end
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. Controller Security
|
|
76
|
+
```ruby
|
|
77
|
+
class ArticlesController < ApplicationController
|
|
78
|
+
before_action :authenticate_user!
|
|
79
|
+
before_action :set_article, only: %i[show edit update destroy]
|
|
80
|
+
|
|
81
|
+
# Add authorization
|
|
82
|
+
def edit
|
|
83
|
+
authorize @article
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. View Improvements
|
|
89
|
+
- Add Tailwind CSS classes
|
|
90
|
+
- Implement responsive design
|
|
91
|
+
- Add Turbo Frame tags for interactivity
|
|
92
|
+
- Ensure accessibility
|
|
93
|
+
|
|
94
|
+
### 4. Route Customization
|
|
95
|
+
```ruby
|
|
96
|
+
resources :articles do
|
|
97
|
+
member do
|
|
98
|
+
patch :publish
|
|
99
|
+
patch :unpublish
|
|
100
|
+
end
|
|
101
|
+
collection do
|
|
102
|
+
get :drafts
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Scaffold Alternatives
|
|
108
|
+
|
|
109
|
+
### Model Only
|
|
110
|
+
```bash
|
|
111
|
+
rails generate model Article title:string body:text
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Controller Only
|
|
115
|
+
```bash
|
|
116
|
+
rails generate controller Articles index show new create edit update destroy
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Migration Only
|
|
120
|
+
```bash
|
|
121
|
+
rails generate migration AddCategoryToArticles category:string
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Best Practices
|
|
125
|
+
|
|
126
|
+
1. **Always add validations** after scaffolding
|
|
127
|
+
2. **Add indexes** for foreign keys and frequently queried fields
|
|
128
|
+
3. **Set up associations** immediately
|
|
129
|
+
4. **Remove unused actions** if not needed
|
|
130
|
+
5. **Style views** with Tailwind before showing to user
|
|
131
|
+
6. **Add tests** for the new resource
|