propel_facets 0.1.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: da6cba3a34b195a31c1b16b7609f418cffd3b4b8ff94f54459a8a8abc2b55155
4
+ data.tar.gz: 119e220c8e5d0bc8f5a63b651bba57c8766a8cfffeecb5c7848bd079b45a8891
5
+ SHA512:
6
+ metadata.gz: ed75a71a012e5740455d6aaadcbc9b374c7a0ad22a4cb7108d6036e00b73b6cc506a084bf744d02d857077e6e4541552015b1ed1fca463bea9706b26228a7b8d
7
+ data.tar.gz: 66d137d4866629b9e392d65abef7d916e66132710a945cbb7c5c8c5bdcd62cbaa7994175dd35f51f17d96136ae4e2d2ea59bf9ef2df5440c6a5c58ecbec26d95
data/CHANGELOG.md ADDED
@@ -0,0 +1,62 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Planned Features
11
+ - Caching system integration with Rails caching (Solid Cache support)
12
+ - Automatic association inclusion configuration
13
+ - Field naming conventions (camelCase, kebab-case, etc.)
14
+ - Metadata inclusion (pagination, counts, etc.)
15
+ - Performance logging and optimization tools
16
+
17
+ ## [0.1.0] - 2025-01-XX
18
+
19
+ ### Added
20
+ - **Self-extracting generator gem architecture** - Install temporarily, extract code, remove dependency
21
+ - **Rails generator system** with install and unpack commands
22
+ - **Model concern (ModelFacet)** for defining JSON facets with inheritance
23
+ - **Controller concerns** for rendering facets and parameter handling:
24
+ - `FacetRenderer` - Connect facets to controller actions
25
+ - `StrongParamsHelper` - Enhanced parameter handling for complex JSON
26
+ - **Complete configuration system** with implemented features only:
27
+ - JSON root structure configuration (`:data`, `:model`, `:class`, `:none`)
28
+ - API format selection (`:rest`, `:jsonapi`, `:openapi`, `:graphql`, etc.)
29
+ - Strict mode for error handling
30
+ - Default facets and inheritance patterns
31
+ - **Error handling system** with custom error classes
32
+ - **API parameter utilities** for complex JSON structures
33
+ - **Comprehensive documentation** and examples
34
+ - **Path gem installation** support for development workflow
35
+ - **Template system** with customizable generators
36
+
37
+ ### Features
38
+ - **Multiple JSON representations** per model with simple DSL
39
+ - **Facet inheritance** with base facets and extension chains
40
+ - **Field and method selection** for precise API responses
41
+ - **Association rendering** with custom facet selection
42
+ - **Configurable JSON root structures** for different API standards
43
+ - **Rails conventions integration** with standard patterns
44
+ - **Zero runtime dependencies** after code extraction
45
+
46
+ ### Technical Implementation
47
+ - Clean generator architecture following Rails conventions
48
+ - Template-based code generation for easy customization
49
+ - Proper Ruby module structure with namespace isolation
50
+ - Comprehensive test suite for generator functionality
51
+ - Documentation-driven development with extensive examples
52
+
53
+ ### Generator Commands
54
+ - `rails generate propel_facets:install` - Install PropelFacets into application
55
+ - `rails generate propel_facets:unpack` - Extract generator for customization
56
+ - Selective unpacking with `--models-only`, `--controllers-only`, etc.
57
+
58
+ ### Self-Extracting Benefits
59
+ - **No runtime gem dependencies** - all code lives in host application
60
+ - **Full customization control** - modify any generated component
61
+ - **Standard Rails patterns** - follows established conventions
62
+ - **Easy maintenance** - no hidden gem complexity in production
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Propel Facets Generator
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,354 @@
1
+ # PropelFacets
2
+
3
+ A Rails generator that provides a flexible system for defining different JSON representations of ActiveRecord models and automatically connecting them to controller actions.
4
+
5
+ ## Installation
6
+
7
+ PropelFacets is designed as a **self-extracting generator gem**. You install it temporarily, run the generators to extract the code into your application, then remove the gem dependency.
8
+
9
+ ### Step 1: Add to Gemfile as a Path Gem
10
+
11
+ ```ruby
12
+ # In your Gemfile
13
+ gem 'propel_facets', path: 'propel_facets'
14
+ ```
15
+
16
+ ### Step 2: Bundle Install
17
+
18
+ ```bash
19
+ bundle install
20
+ ```
21
+
22
+ ### Step 3: Unpack the Generator (Optional)
23
+
24
+ If you want to customize the generator templates:
25
+
26
+ ```bash
27
+ rails generate propel_facets:unpack
28
+ ```
29
+
30
+ This extracts the generator into `lib/generators/propel_facets/` for customization.
31
+
32
+ ### Step 4: Install PropelFacets
33
+
34
+ ```bash
35
+ rails generate propel_facets:install
36
+ ```
37
+
38
+ This installs the facets system including model and controller concerns, utilities, and configuration.
39
+
40
+ ### Step 5: Remove Gem Dependency (Optional)
41
+
42
+ After installation, you can remove the gem from your Gemfile. All functionality remains in your application.
43
+
44
+ ## Quick Start
45
+
46
+ ### In Models
47
+
48
+ Define different JSON representations using facets:
49
+
50
+ ```ruby
51
+ class User < ApplicationRecord
52
+ # Basic facet with specific fields
53
+ json_facet :summary, fields: [:id, :name, :email, :created_at]
54
+
55
+ # Extended facet building on another
56
+ json_facet :details, base: :summary,
57
+ fields: [:updated_at],
58
+ methods: [:full_name],
59
+ include: [:posts]
60
+
61
+ # Association facets
62
+ json_facet :with_posts, base: :summary, include: [:posts]
63
+
64
+ # Custom method
65
+ def full_name
66
+ "#{first_name} #{last_name}"
67
+ end
68
+ end
69
+ ```
70
+
71
+ ### In Controllers
72
+
73
+ Connect facets to controller actions:
74
+
75
+ ```ruby
76
+ class UsersController < ApplicationController
77
+ include FacetRenderer
78
+ include StrongParamsHelper
79
+
80
+ connect_facet :summary, actions: [:index]
81
+ connect_facet :details, actions: [:show, :update]
82
+
83
+ permitted_params :name, :email, :role
84
+
85
+ def index
86
+ users = User.all
87
+ render json: { data: users.map { |user| resource_json(user) } }
88
+ end
89
+
90
+ def show
91
+ user = User.find(params[:id])
92
+ render json: { data: resource_json(user) }
93
+ end
94
+ end
95
+ ```
96
+
97
+ ### Enhanced Parameter Handling
98
+
99
+ For complex JSON parameters:
100
+
101
+ ```ruby
102
+ class ProductsController < ApplicationController
103
+ include StrongParamsHelper
104
+
105
+ permitted_params :name, :price, :category
106
+ permitted_unknown_params :metadata, :settings # For dynamic JSON structures
107
+
108
+ def create
109
+ # Handles both strong params and unknown params
110
+ product = Product.new(resource_params)
111
+ # ...
112
+ end
113
+ end
114
+ ```
115
+
116
+ ## Features
117
+
118
+ ### Flexible JSON Representations
119
+ - **Multiple facets per model** - Define various JSON views for different contexts
120
+ - **Facet inheritance** - Build complex facets by extending simpler ones
121
+ - **Field selection** - Include specific model attributes
122
+ - **Method inclusion** - Include results of model methods
123
+ - **Association rendering** - Include related models with their own facets
124
+
125
+ ### Controller Integration
126
+ - **Automatic facet-action mapping** - Connect specific facets to controller actions
127
+ - **Resource JSON rendering** - Simple method to render models with appropriate facets
128
+ - **Enhanced parameter handling** - Support for complex JSON structures
129
+ - **Strong parameters extension** - Handles both known and unknown parameters
130
+
131
+ ### Configuration System
132
+ - **JSON root structures** - Configure response format (`:data`, `:model`, `:class`, `:none`)
133
+ - **API format standards** - Support for REST, JSON:API, OpenAPI, GraphQL formats
134
+ - **Strict mode** - Control error handling for missing facets
135
+ - **Default facets** - Set up standard facets across all models
136
+
137
+ ### Rails Integration
138
+ - **ApplicationRecord defaults** - Standard facets available on all models
139
+ - **ActiveStorage support** - Automatic attachment URL handling
140
+ - **Standard Rails patterns** - Follows Rails conventions throughout
141
+ - **Zero dependencies** - No runtime gem dependencies after extraction
142
+
143
+ ## Facet Options
144
+
145
+ When defining facets, you can use these options:
146
+
147
+ - **`fields`**: Array of model attributes to include
148
+ - **`methods`**: Array of model methods to call and include
149
+ - **`include`**: Array of associations to include (uses association name as JSON key)
150
+ - **`include_as`**: Hash of associations with custom JSON key names
151
+ - **`base`**: Name of another facet to extend from
152
+
153
+ ```ruby
154
+ class Article < ApplicationRecord
155
+ # Basic reference facet
156
+ json_facet :reference, fields: [:id, :title]
157
+
158
+ # Summary extends reference
159
+ json_facet :summary, base: :reference, fields: [:excerpt, :published_at]
160
+
161
+ # Details with methods and associations
162
+ json_facet :details, base: :summary,
163
+ methods: [:word_count, :reading_time],
164
+ include: [:author], # Will appear as "author" in JSON
165
+ include_as: [comments: :feedback] # Will appear as "feedback" in JSON
166
+ end
167
+ ```
168
+
169
+ ## Default Facets
170
+
171
+ All models inherit these default facets from `ApplicationRecord`:
172
+
173
+ - **`:reference`** - Basic id and type information
174
+ - **`:included`** - Extends reference facet
175
+ - **`:short`** - General purpose summary view
176
+ - **`:details`** - Comprehensive view with more fields
177
+
178
+ ```ruby
179
+ # These are automatically available on all models:
180
+ User.first.as_json(facet: :reference) # => { "id": 1, "type": "User" }
181
+ User.first.as_json(facet: :short) # => More fields based on inheritance
182
+ ```
183
+
184
+ ## Configuration
185
+
186
+ Configure PropelFacets in `config/initializers/propel_facets.rb`:
187
+
188
+ ```ruby
189
+ PropelFacets.configure do |config|
190
+ # JSON root structure: :data, :model, :class, :none
191
+ # :data => { "data": { "id": 1, "name": "John" } }
192
+ # :model => { "user": { "id": 1, "name": "John" } }
193
+ # :none => { "id": 1, "name": "John" }
194
+ config.root = :data
195
+
196
+ # API format standard: :rest, :jsonapi, :openapi, :graphql
197
+ config.api_format = :rest
198
+
199
+ # Default facets available on all models
200
+ config.default_facets = %w[reference included short details]
201
+
202
+ # Error handling: raise errors (true) or show warnings (false)
203
+ config.strict_mode = false
204
+
205
+ # Default base facet for inheritance chains
206
+ config.default_base_facet = :reference
207
+ end
208
+ ```
209
+
210
+ ## Advanced Usage
211
+
212
+ ### Complex Facet Inheritance
213
+
214
+ ```ruby
215
+ class Product < ApplicationRecord
216
+ # Base facets
217
+ json_facet :reference, fields: [:id, :name]
218
+ json_facet :pricing, fields: [:price, :currency]
219
+
220
+ # Combine multiple facets
221
+ json_facet :listing, base: :reference,
222
+ fields: [:description, :availability],
223
+ methods: [:formatted_price]
224
+
225
+ # Full details combining multiple concerns
226
+ json_facet :admin, base: :listing,
227
+ fields: [:cost, :margin, :created_at],
228
+ include: [:supplier, :reviews]
229
+ end
230
+ ```
231
+
232
+ ### Dynamic Parameter Handling
233
+
234
+ ```ruby
235
+ class ApiController < ApplicationController
236
+ include StrongParamsHelper
237
+
238
+ # Handle known parameters
239
+ permitted_params :name, :email, :status
240
+
241
+ # Handle dynamic JSON structures
242
+ permitted_unknown_params :preferences, :metadata, :custom_fields
243
+
244
+ private
245
+
246
+ def resource_params
247
+ # Returns both strong params and unknown params merged
248
+ super
249
+ end
250
+ end
251
+ ```
252
+
253
+ ### Custom JSON Formatting
254
+
255
+ ```ruby
256
+ # Configure different JSON root structures
257
+ PropelFacets.configure do |config|
258
+ config.root = :none # Flat JSON structure
259
+ end
260
+
261
+ # Result:
262
+ User.first.as_json(facet: :summary)
263
+ # => { "id": 1, "name": "John", "email": "john@example.com" }
264
+
265
+ # vs. with config.root = :data:
266
+ # => { "data": { "id": 1, "name": "John", "email": "john@example.com" } }
267
+ ```
268
+
269
+ ## Self-Extracting Architecture
270
+
271
+ PropelFacets follows a self-extracting pattern that provides:
272
+
273
+ - **No runtime dependencies** - all code lives in your application
274
+ - **Full control** - modify any component after installation
275
+ - **No black boxes** - transparent, readable Rails code
276
+ - **Easy maintenance** - standard Rails patterns throughout
277
+
278
+ After installation, you can:
279
+ - Remove the gem from your Gemfile
280
+ - Customize all generated code
281
+ - Maintain and extend functionality independently
282
+ - Modify facet behavior for your specific needs
283
+
284
+ ## Generated Files
285
+
286
+ After installation, PropelFacets creates:
287
+
288
+ ### Model Support
289
+ - `app/models/concerns/model_facet.rb` - Facet definition DSL for models
290
+ - `app/models/application_record.rb` - Base model with default facets (if needed)
291
+
292
+ ### Controller Support
293
+ - `app/controllers/concerns/facet_renderer.rb` - Controller facet rendering
294
+ - `app/controllers/concerns/strong_params_helper.rb` - Enhanced parameter handling
295
+
296
+ ### Utilities
297
+ - `lib/api_params.rb` - API parameter utility class
298
+
299
+ ### Error Handling
300
+ - `app/errors/application_error.rb` - Base error class
301
+ - `app/errors/missing_facet.rb` - Facet-specific error handling
302
+
303
+ ### Configuration
304
+ - `config/initializers/propel_facets.rb` - PropelFacets configuration
305
+
306
+ ### Documentation
307
+ - `doc/json_facet.md` - Complete usage documentation and examples
308
+
309
+ ## Integration with PropelApi
310
+
311
+ PropelFacets integrates seamlessly with PropelApi for complete API development:
312
+
313
+ ```ruby
314
+ # Install both systems
315
+ rails generate propel_api:install --adapter=propel_facets
316
+ rails generate propel_facets:install
317
+
318
+ # Generated API controllers automatically use facets
319
+ class Api::V1::UsersController < Api::V1::ApiController
320
+ connect_facet :short, actions: [:index]
321
+ connect_facet :details, actions: [:show, :create, :update]
322
+
323
+ # Facet rendering is automatic
324
+ end
325
+ ```
326
+
327
+ ## Development
328
+
329
+ ```bash
330
+ # Run facets tests
331
+ cd propel_facets
332
+ bundle exec rake test
333
+
334
+ # Test specific functionality
335
+ bundle exec ruby -Ilib:test test/propel_facets_generator_test.rb
336
+ ```
337
+
338
+ ## Roadmap
339
+
340
+ ### Planned Features
341
+ - **Caching integration** - Rails caching support for rendered facets
342
+ - **Field naming conventions** - camelCase, kebab-case transformations
343
+ - **Metadata inclusion** - Pagination, counts, timestamps
344
+ - **Performance logging** - Monitor facet rendering performance
345
+ - **Nested depth limits** - Prevent infinite recursion
346
+ - **Type information** - Include model type data in JSON
347
+
348
+ ## Contributing
349
+
350
+ Bug reports and pull requests are welcome on GitHub.
351
+
352
+ ## License
353
+
354
+ The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,130 @@
1
+ # PropelFacets
2
+
3
+ A Rails generator that provides a flexible system for defining different JSON representations of ActiveRecord models and automatically connecting them to controller actions.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'propel_facets'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ $ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```bash
22
+ $ gem install propel_facets
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Generate the PropelFacets system in your Rails application:
28
+
29
+ ```bash
30
+ $ bin/rails generate propel_facets
31
+ ```
32
+
33
+ This will create:
34
+
35
+ - `app/models/concerns/model_facet.rb` - Model concern for defining facets
36
+ - `app/controllers/concerns/facet_renderer.rb` - Controller concern for rendering facets
37
+ - `app/controllers/concerns/strong_params_helper.rb` - Enhanced parameter handling
38
+ - `lib/api_params.rb` - API parameter utility class
39
+ - `app/errors/application_error.rb` - Base error class
40
+ - `app/errors/missing_facet.rb` - Facet-specific error class
41
+ - `app/models/application_record.rb` - Base model with default facets (if doesn't exist)
42
+ - `doc/json_facet.md` - Complete documentation
43
+
44
+ ## Quick Start
45
+
46
+ ### In Models
47
+
48
+ Define different JSON representations using facets:
49
+
50
+ ```ruby
51
+ class User < ApplicationRecord
52
+ # Basic facet with specific fields
53
+ json_facet :short, fields: [:name, :email, :created_at]
54
+
55
+ # Extended facet building on another
56
+ json_facet :details, base: :short,
57
+ fields: [:updated_at],
58
+ methods: [:full_name],
59
+ include: [:posts]
60
+ end
61
+ ```
62
+
63
+ ### In Controllers
64
+
65
+ Connect facets to controller actions:
66
+
67
+ ```ruby
68
+ class UsersController < ApplicationController
69
+ include FacetRenderer
70
+ include StrongParamsHelper
71
+
72
+ connect_facet :short, actions: [:index]
73
+ connect_facet :details, actions: [:show]
74
+
75
+ permitted_params :name, :email, :role
76
+
77
+ def index
78
+ users = User.all
79
+ render json: { data: users.map { |u| resource_json(u) } }
80
+ end
81
+ end
82
+ ```
83
+
84
+ ### Parameter Handling
85
+
86
+ For complex JSON parameters:
87
+
88
+ ```ruby
89
+ class ProductsController < ApplicationController
90
+ include StrongParamsHelper
91
+
92
+ permitted_params :name, :price, :category
93
+ permitted_unknown_params :metadata, :settings # For dynamic JSON structures
94
+ end
95
+ ```
96
+
97
+ ## Features
98
+
99
+ - **Flexible JSON representations** with facet inheritance
100
+ - **Automatic controller-action mapping**
101
+ - **Strong parameters with JSON support** including complex structures
102
+ - **Active Storage attachment handling**
103
+ - **Comprehensive error handling**
104
+ - **Rails-like conventions** and familiar patterns
105
+
106
+ ## Documentation
107
+
108
+ After installation, see `doc/json_facet.md` for complete documentation including:
109
+
110
+ - Advanced facet options
111
+ - Parameter handling patterns
112
+ - Error handling
113
+ - Best practices
114
+
115
+ ## Development
116
+
117
+ To test the generator:
118
+
119
+ ```bash
120
+ $ cd lib/generators/propel_facets
121
+ $ ruby test/propel_facets_generator_test.rb
122
+ ```
123
+
124
+ ## Contributing
125
+
126
+ Bug reports and pull requests are welcome on GitHub.
127
+
128
+ ## License
129
+
130
+ The gem is available as open source under the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,68 @@
1
+ Description:
2
+ PropelFacets is a self-extracting generator gem that provides a flexible system for
3
+ defining different JSON representations of your ActiveRecord models and automatically
4
+ connecting them to controller actions.
5
+
6
+ Installation:
7
+ 1. Add to Gemfile: gem 'propel_facets', path: 'lib/propel_facets'
8
+ 2. Run: bundle install
9
+ 3. Optionally unpack: bin/rails generate propel_facets:unpack
10
+ 4. Install: bin/rails generate propel_facets:install
11
+ 5. Optionally remove gem from Gemfile (functionality remains)
12
+
13
+ Example:
14
+ bin/rails generate propel_facets:install
15
+
16
+ This will create:
17
+ config/initializers/propel_facets.rb - Configuration file
18
+ app/models/concerns/model_facet.rb - Model concern for defining facets
19
+ app/controllers/concerns/facet_renderer.rb - Controller concern for rendering facets
20
+ app/controllers/concerns/strong_params_helper.rb - Enhanced parameter handling
21
+ lib/api_params.rb - API parameter utility class
22
+ app/errors/application_error.rb - Base error class
23
+ app/errors/missing_facet.rb - Facet-specific error class
24
+ doc/json_facet.md - Complete documentation
25
+ app/models/application_record.rb - Base model with default facets (if doesn't exist)
26
+
27
+ Unpack Generator:
28
+ bin/rails generate propel_facets:unpack # Extract generator for customization
29
+ bin/rails generate propel_facets:unpack --templates-only # Only templates
30
+ bin/rails generate propel_facets:unpack --models-only # Only model templates
31
+ bin/rails generate propel_facets:unpack --controllers-only # Only controller templates
32
+ bin/rails generate propel_facets:unpack --errors-only # Only error templates
33
+ bin/rails generate propel_facets:unpack --lib-only # Only lib templates
34
+ bin/rails generate propel_facets:unpack --docs-only # Only documentation
35
+
36
+ Quick Start Usage:
37
+ In models, define facets for different JSON representations:
38
+ class User < ApplicationRecord
39
+ json_facet :summary, fields: [:id, :name, :email]
40
+ json_facet :details, base: :summary, fields: [:created_at], methods: [:full_name]
41
+ end
42
+
43
+ In controllers, connect facets to actions:
44
+ class UsersController < ApplicationController
45
+ include FacetRenderer
46
+ include StrongParamsHelper
47
+
48
+ connect_facet :summary, actions: [:index]
49
+ connect_facet :details, actions: [:show]
50
+
51
+ permitted_params :name, :email, :role
52
+ end
53
+
54
+ Configuration:
55
+ Configure in config/initializers/propel_facets.rb:
56
+ PropelFacets.configure do |config|
57
+ config.root = :data # JSON root structure
58
+ config.api_format = :rest # API format standard
59
+ config.strict_mode = false # Error handling mode
60
+ end
61
+
62
+ Self-Extracting Architecture:
63
+ PropelFacets is designed to be installed temporarily, extract its functionality
64
+ into your application, then be removed. This ensures:
65
+ - No runtime gem dependencies
66
+ - Full control over all generated code
67
+ - Easy customization of all components
68
+ - Standard Rails patterns throughout