Description
Build an initial implementation of Model Scope.
Example usage
As an end user, I'd like to install a gem and run a Rake task to get the report:
$ bundle add modelscope --group development
$ bin/rails modelscope:callbacks
Model Scope callbacks report:
Model | Kind | Total | Own | Inherited | Rails | Gems | Conditional |
------|--------------|-------|-----|-----------|-------|------|-------------|
User | all | 23 | 5 | 2 | 8 | 8 | 21 |
| b/validation | 3 | 1 | 0 | 1 | 1 | 2 |
| a/save | 13 | 5 | 4 | 3 | 2 | 4 |
# ...
The rails modelscope:validations task works in a similar fashion.
The key features in the example:
- The library should work without requiring adding any custom code; just adding the gem to the bundle should be enough to use it.
- For each model we show the total number of callbacks in two dimensions: callback kind (
before_create,after_save, etc.) and origin distributions (where the callback is defined). We also count conditional callbacks separately.
References
There is an outdated project called arca, which has some code (for older Rails versions) to get the callbacks information from models.
Feel free to re-use its parts if you find them useful.
Tasks
- [x] Research the possibility of extending the set of parameters to analyze callbacks (right now we have "kind", "origin", "conditional" — what else could be useful?)
- [x] Implement core functionality for callbacks (an API which accepts a model class and returns all the data)
- [x] Come up with the set of paramters for validations — what information can we get from Active Record, which could be useful?
- [x] Implement core functionality for validations
- [x] Implement a Rake task with table-like output for console (it's okay to use gems to format the output — we aim for a good UX)
- [x] Don't forget about tests/CI at all stages.
Future considerations
Please, keep in mind the potential future extensions when designing a library:
- Different output formats/modes support (JSON, Web UI, etc.)
- Ability to filter models by name.
- Modular architecture support (multiple
app/modelsdirectories).
Development log
Structure: Runner runs the task, Collector collects Callback's, Callback represends a single "find", Stats does the stats for reports if needed, Report formats the existing data (several kinds of reports).
Table report done via terminal-table.
Added the line report format for debugging. Also added github report format for GitHub Actions (reference: Rubocop).
model parameter for the rake tasks supports both class names and relative file names.
Now supporting paths parameter for extra paths, and auto loading models from Rails Engines.
Integration specs are done using checking the output of line formatter.
Unit tests are simple, the actual logic is in the integration tests.
Re: "Research the possibility of extending the set of parameters to analyze callbacks" added two categories of callbacks: caused by attributes, and caused by associations.
Added rake modelscope:validations that heavily reuses existing code.
Using custom matchers to check for callbacks. And custom matchers for validations. Lots of integration tests.
TODO: rename. callback_hell is a nice name. modelscope is taken.
Model Scope
Model scope analyzes your Rails application models and provides some useful insights on callbacks and validations defined. This information can be used to idenfity classes which would benefit from refactoring (extracting callbacks/validations from models to other abstraction layers).
Installation
Add to your project's Gemfile:
gem "modelscope", group: :development
Supported Ruby versions
- Ruby (MRI) >= 2.7.0
- Rails >= 6.0
Usage
TBD
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/evilmartians/modelscope.
Credits
This gem is generated via new-gem-generator.
License
The gem is available as open source under the terms of the MIT License.