Active Support has a nifty little helper that can cut down on repetition. A lot of things in Rails like validations, associations, named_scopes, routes etc… take a hash of options as their final parameter. There are times where you use many of these with some common options, for example
1 2 3 4 5
or maybe you have a bunch of associations which all share an association proxy extension module and some settings
1 2 3 4 5
1 2 3 4 5 6 7
Any time you’ve got a bunch of method calls taking some common options,
with_options can help.
So how does it work on the inside? All the
with_options method actually does is yield a special object to its block – all the craftiness is in that object. What we want that object to do is forward method calls to the object we’re really interested in (in this case the Customer class) adding the options before it does so.
As with many such proxy objects we undefine just about every method and just implement
method_missing. The implementation of
method_missing inspects the arguments and merges any options present with the common set defined by the call to
with_options (so individual methods can take extra options or override the common ones) before passing them onto the “real” object.
Originally a limitation was that the last argument just had to be a hash, so for example if you had a procedural
with_options couldn’t work. Luckily a recent commit rectifies this: if the thing you’re trying to merge with is a proc, then
with_options will replace it with a new proc that merges the common options with the result of the call to the original proc. If you’re not on edge you’ll have to wait for 2.3 in order to get this.
While both the examples I gave showed using
with_options on what is essentially model class configuration it is by no means limited to that. You could use it for that sort of configuration on your own classes or just inside a regular method – anytime you are making several method calls on the same object with a hash of options at the end.