One of Rails largest strengths are the generators. It is absolute magic to have basic CRUD in place with one scaffold command. I remember being so damned jealous of the Rails cohort in our bootcamp (while coding express.js CRUD by hand like a fool). I remember the first time I used it at a job, feeling like a genius. It’s really powerful and cool!!!
However, if untended, the generators become obsolete and unused. Use Pundit for authorization, and now you have to add authorize @record
to every generated controller method . Every such addition makes the defaults less useful.
Devs start to copy and paste files from other (proven to work) portions of the app. Or they have AI generate the boilerplate for them. Possibly with results suitable for most apps, but not tailored to their app. Possibly with code polluted by older patterns used within the same project. In my opinion, the deterministic nature of the generators is preferable to AI. The generator route allows you to spell out EXACTLY how you want your app to behave, toe to tip. You have control.
Sure, you could replace the generators with your own custom generators, and ensure the team uses them somehow. However, customizing the thor templates solves most of these concerns, and lets devs use the standard, well-known generators.
My ideal would be running a generator/command, to import all the applicable templates into my lib/templates directory.
I started to create a plugin that would add a --template-copy
option to generators. This option would import .tt files into the appropriate folder as the generators are used. I don’t love adding an option that is only really useful once per generator… but it was the easiest thing to implement quickly.
Another approach might be to create a TemplateGenerator that accepts another Generator as an argument, and copies its templates into the appropriate directory…
After some success and some frustration, I learned about the rails app:template:copy
command. This is ALMOST what I was hoping rails would have. It has a couple of shortcomings:
-
As a task, it cannot use the generator
hook_for
method to grab rspec, factory_bot, draper, or other gems’ template files. Such as the model_spec template which would run alongside the model generator. It would be nice if gems could connect to it, or at least adopt the same pattern. Say,rspec:templates:copy
-
It is NOT DOCUMENTED. It has been hidden from
rake -T
since 2010, and is not even mentioned in the guides (Creating and Customizing Rails Generators & Templates — Ruby on Rails Guides). Side note: It is not very clear from the guides exactly where you should create/copy template files, though some examples of valid locations are given.
I can see some problems/difficulties with all of the above approaches… I’m thinking the CustomTemplateGenerator could mimic app:templates:copy but also use hook_for so that gems could use the same pattern…
At this point, I am just raising the question and asking for input. Are other people as frustrated by this as I am? Is there an easier approach? Are you all just copying files from gems? Building from scratch? Ignoring altogether? What would be your ideal generator/template customization setup be? Is there a good reason Rails set the template copy approach aside over a decade ago?