# Transforming arguments to find\_by

**URL:** <https://www.ruby-forum.com/t/transforming-arguments-to-find-by/183407>\
**Category:** Rails\
**Created:** [February 13, 2010, 9:01am UTC](https://www.ruby-forum.com/t/transforming-arguments-to-find-by/183407 "2010-02-13T09:01:02Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![acreadinglist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ccd318/32.png) [@acreadinglist](https://www.ruby-forum.com/u/acreadinglist)\
**Post date:** [February 13, 2010, 9:01am UTC](https://www.ruby-forum.com/t/transforming-arguments-to-find-by/183407/1 "2010-02-13T09:01:02Z")

</div>

I have a model that contains a “normalized” 10-digit US phone  
number.

I’d like my find\_by\_phone\_number method (and its variants) to be able  
to take unnormalized forms (eg, +1(555)555-5555). Is there a way for  
me to modify the dynamic find methods to perform my  
PhoneNumberHelper::normalize on the argument, without having to  
replace all of the dynamic methods with my own versions?

Thanks,  
Andrew

---

<div class="post-metadata">

**Author:** ![acreadinglist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ccd318/32.png) [@acreadinglist](https://www.ruby-forum.com/u/acreadinglist)\
**Post date:** [February 13, 2010, 3:19pm UTC](https://www.ruby-forum.com/t/transforming-arguments-to-find-by/183407/2 "2010-02-13T15:19:39Z")

</div>

On 13 February 2010 07:59, acreadinglist [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> without having to  
> replace all of the dynamic methods with my own versions?

Essentially, I’d say “no”.  
There wouldn’t be an easy way for the dynamic find\_by\_xyz to normalize  
your data, as it wouldn’t know which “helper” methods to call,

The easiest solution is to create a find\_by\_phone\_number method of  
your own in your model, in which you do your normalizing, and then do  
a find with conditions.

But it you want to delve into the Rails source code and monkey-patch  
the method\_missing? method that does the magic “find bys” (I can’t  
recall where it would be off the top of my head), that might be your  
best route if you _really_ want it all done magically (personally, I  
prefer custom code like that in the models, where I know where to find  
it - especially when I’m looking again in six months and can’t  
remember how everything hangs together!)

Just as an aside, why don’t you do the normalizing before you call the  
find\_by? … pass in the normalized value as normal?

---

<div class="post-metadata">

**Author:** ![acreadinglist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ccd318/32.png) [@acreadinglist](https://www.ruby-forum.com/u/acreadinglist)\
**Post date:** [February 19, 2010, 7:29am UTC](https://www.ruby-forum.com/t/transforming-arguments-to-find-by/183407/3 "2010-02-19T07:29:50Z")

</div>

Thanks for the response Michael.

I agree, better to have the code in the models than monkey patching  
Rails.

And to that end, I am doing what you asked about last - normalizing  
before passing it in. But it just feels like the wrong solution. It  
forces me to put normalization calls in a bunch of places in the code;  
if I could normalize in the find automatically, it would only be in  
one place in the code, and nobody (just me for now, but who knows  
eventually) would have to remember to normalize a number before  
passing it in.

---

<div class="post-metadata">

**Author:** ![acreadinglist](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ccd318/32.png) [@acreadinglist](https://www.ruby-forum.com/u/acreadinglist)\
**Post date:** [February 19, 2010, 9:52am UTC](https://www.ruby-forum.com/t/transforming-arguments-to-find-by/183407/4 "2010-02-19T09:52:41Z")

</div>

On 19 February 2010 06:28, acreadinglist [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> eventually) would have to remember to normalize a number before  
> passing it in.

I like to follow the pattern of fixing one, and only one, problem at a  
time; first, get the finder working, then move onto the next task.  
In this case the next task is to dry up all that normalization…

so you’ve got something like this duplicated in lots of controllers:

# controller

phone\_number = phone\_number\_normalize\_method(params[:phone\_number])  
@people = Person.find\_by\_phone\_number(phone\_number)

(hopefully the “phone\_number\_normalize\_method” is somewhere shared,  
not copied into every controller… 😉

so to save having to remember to normalize, extract that pattern as a  
class method on Person; so the process becomes:

# controller

@people =  
Person.normalize\_and\_find\_by\_phone\_number(params[:phone\_number])

# Person model

def self.normalize\_and\_find\_by\_phone\_number(phone\_number)  
Person.find\_by\_phone\_number(phone\_number\_normalize\_method(phone\_number))  
end
