If you're like me and have an application with some pockets of very outdated Rails idioms, you may have code like this in your controllers:
This can of course be rewritten to use a
Hash as the second argument to
And there's a similar, but slightly different, transformation that can be made for setting
error flash messages:
I had a bunch of these changes that needed fixing up, and it would have taken around 15 minutes to search around the codebase and fix all the references. But why do in 15 minutes what you can automate in a weekend? I've written about synvert before and it's the perfect tool for automating this transformation. Thus, a new synvert rule:
This whipped right through the codebase I was working on and fixed up most occurrences in a jiffy. A few notes:
- Setting local variables feels clumsy. When the rule encounters a flash setting it needs to shift into a different state where now it's checking the next line for a
redirect_toinvocation. I'm not sure of a nicer way to express this though.
- Creating a
Rewriter::RemoveActionand then maybe discarding it feels similarly clumsy.
- As Richard initially pointed out on the PR it needed to check more types of flash; I fixed that up.
- This misses cases where the flash setting and the
redirect_toare not on adjacent lines. To sort through that we would need to do data flow analysis. This is challenging in a dynamically typed language, but perhaps we could do something on the basic block level. Perhaps a future effort...
- Having done a rule in the past and knowing the mechanics of iterating on it helped a lot. No mystery there, except that it was nice to refer back to my own blog post for how to do that.
- I didn't realize how long this Action Pack feature has been available. It was committed by DHH in 2009! Way back when...
- Edit: This rule is in synvert-snippets now, so if you have synvert installed and do a
synvert --sync && synvert -r rails/redirect_with_flashit'll fix up your code.
Takeaways are that synvert continues to be a very handy tool, that it's worth rescanning the Rails API docs occasionally to see what you've missed, and that automating tedious things is good fun!