# Find\_by\_like?

**URL:** <https://www.ruby-forum.com/t/find-by-like/82053>\
**Category:** Rails\
**Created:** [January 17, 2007, 2:10am UTC](https://www.ruby-forum.com/t/find-by-like/82053 "2007-01-17T02:10:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [January 17, 2007, 2:10am UTC](https://www.ruby-forum.com/t/find-by-like/82053/1 "2007-01-17T02:10:47Z")

</div>

Hi all,

Last night a friend and I decided to try and implement a search feature  
for a website (one we are using to learn Rails). We have a membership  
database and thought it would be good to search for members based on  
their surname (starting easy and working up) - this was pretty easy:

Member.find\_all\_by\_surname(params[:query])

OK - What if you don’t know the exact surname, or what a list of every  
member with “cla” in their surname?

Our solution late last night was:

Member.find(:all, :conditions =\> [“surname LIKE ?”, “%” +  
params[:query] + “%”])

It works but it does not seem very “rails like”, so this morning I went  
looking for a :like or find\_by\_surname\_like - it seems none exist.

So my question is this - how do other people implement these kind of  
searches?

Is these a case to be made for adding “like” support to rails?

If so - what should it look like? Here are some ideas:

Member.find\_by\_surname\_like(“cla”)  
Member.find\_all\_by\_surname\_like(“cla”)  
Member.find\_surname\_like(“cla”)  
Member.find\_like\_surname(“cla”)  
Member.find(:like =\> {â€œSurnameâ€œ =\> “cla”})

Personally I prefer the first one. Josh S. has a good article on  
how dynamic finders work  
([http://blog.hasmanythrough.com/2006/08/13/how-dynamic-finders-work](http://blog.hasmanythrough.com/2006/08/13/how-dynamic-finders-work)), so  
this would make an interesting project for me to get my hands dirty in  
Rails code. I also notice a proposed fulltext search on the wiki  
([http://wiki.rubyonrails.org/rails/pages/FullTextSearch](http://wiki.rubyonrails.org/rails/pages/FullTextSearch)).

But before I have a go at this - how do you think something like this  
should work?

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [January 17, 2007, 3:24am UTC](https://www.ruby-forum.com/t/find-by-like/82053/2 "2007-01-17T03:24:33Z")

</div>

> Our solution late last night was:
> 
> Member.find(:all, :conditions =\> [“surname LIKE ?”, “%” +  
> params[:query] + “%”])
> 
> It works but it does not seem very “rails like”, so this morning I went  
> looking for a :like or find\_by\_surname\_like - it seems none exist.
> 
> So my question is this - how do other people implement these kind of  
> searches?

Like you’ve done above, but I tend to usee:

[“surname LIKE ?”, “%{params[:query]}%”]

> Is these a case to be made for adding “like” support to rails?

Not for me, but then again, I’m not everybody 🙂 One potential problem  
is  
once you add like someone is going to want regex (ie. the ~ operator in  
postgres for example) and they’ll probably also want “NOT LIKE” and then  
there’s the whole issue of case [in]sensitivity between databases…

I’m just saying that there’s a lot of options and they tend to get  
somewhat database specific so maybe it’s a hard thing to generalize.

Also, if you did to “like”, I’d also like “begins\_with” that left off  
the  
initial ‘%’… and so on 🙂

> If so - what should it look like? Here are some ideas:
> 
> Member.find\_by\_surname\_like(“cla”)  
> Member.find\_all\_by\_surname\_like(“cla”)  
> Member.find\_surname\_like(“cla”)  
> Member.find\_like\_surname(“cla”)

How are you going to distinguish these methods operating on a model with  
a  
column “surname” vs a column “surname\_like”. Granted that’s an odd name  
for a table column, but it could happen.

> Member.find(:like =\> { Surname =\> “cla”})

This seems so close to just using the :conditions I don’t see the  
point…

> Personally I prefer the first one. Josh S. has a good article on  
> how dynamic finders work  
> ([has\_many :through - How dynamic finders work](http://blog.hasmanythrough.com/2006/08/13/how-dynamic-finders-work)), so  
> this would make an interesting project for me to get my hands dirty in  
> Rails code. I also notice a proposed fulltext search on the wiki  
> ([http://wiki.rubyonrails.org/rails/pages/FullTextSearch](http://wiki.rubyonrails.org/rails/pages/FullTextSearch)).
> 
> But before I have a go at this - how do you think something like this  
> should work?

For me, no, but don’t let me stop you 🙂

-philip

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [January 17, 2007, 5:02am UTC](https://www.ruby-forum.com/t/find-by-like/82053/3 "2007-01-17T05:02:45Z")

</div>

Philip H. wrote:

> Like you’ve done above, but I tend to usee:
> 
> [“surname LIKE ?”, “%{params[:query]}%”]

That’s a little more readable.

> > Is these a case to be made for adding “like” support to rails?
> 
> Not for me, but then again, I’m not everybody 🙂 One potential problem  
> is  
> once you add like someone is going to want regex (ie. the ~ operator in  
> postgres for example) and they’ll probably also want “NOT LIKE” and then  
> there’s the whole issue of case [in]sensitivity between databases…
> 
> I’m just saying that there’s a lot of options and they tend to get  
> somewhat database specific so maybe it’s a hard thing to generalize.
> 
> Also, if you did to “like”, I’d also like “begins\_with” that left off  
> the  
> initial ‘%’… and so on 🙂

Ughh.

> > If so - what should it look like? Here are some ideas:
> > 
> > Member.find\_by\_surname\_like(“cla”)  
> > Member.find\_all\_by\_surname\_like(“cla”)  
> > Member.find\_surname\_like(“cla”)  
> > Member.find\_like\_surname(“cla”)
> 
> How are you going to distinguish these methods operating on a model with  
> a  
> column “surname” vs a column “surname\_like”. Granted that’s an odd name  
> for a table column, but it could happen.

Fair point, but this is not much different to accidentally overriding  
any other existing method.

A bit more searching revealed TextSearch  
([http://wiki.rubyonrails.org/rails/pages/TextSearch](http://wiki.rubyonrails.org/rails/pages/TextSearch)), which seems like a  
more elegant solution in a lot of ways…

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [January 17, 2007, 5:51am UTC](https://www.ruby-forum.com/t/find-by-like/82053/4 "2007-01-17T05:51:07Z")

</div>

Matt J. wrote:

> On 1/16/07, Andrew S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > OK - What if you don’t know the exact surname, or what a list of every  
> > member with “cla” in their surname?
> 
> You might want to check out acts\_as\_ferret - it is overkill for just  
> looking at  
> surnames, but your introduction seemed to indicate you’ll want to search  
> for  
> more things real-soon-now…

Yes - the next step would have been to widen the search to include other  
columns, tables, models, etc.

This plugin has successfully killed any notion of building my own.  
Please move along, nothing to see here…

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [January 17, 2007, 5:07am UTC](https://www.ruby-forum.com/t/find-by-like/82053/5 "2007-01-17T05:07:55Z")

</div>

On 1/16/07, Andrew S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> OK - What if you don’t know the exact surname, or what a list of every  
> member with “cla” in their surname?

You might want to check out acts\_as\_ferret - it is overkill for just  
looking at  
surnames, but your introduction seemed to indicate you’ll want to search  
for  
more things real-soon-now…

–  
Matt J.  
removed\_email\_address@domain.invalid  
President/Technical Director, Acme Art Company ([acmeartco.org](http://acmeartco.org))

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [January 17, 2007, 7:09am UTC](https://www.ruby-forum.com/t/find-by-like/82053/6 "2007-01-17T07:09:09Z")

</div>

> > Also, if you did to “like”, I’d also like “begins\_with” that left off the  
> > initial ‘%’… and so on 🙂
> 
> Ughh.

🙂

> Fair point, but this is not much different to accidentally overriding any  
> other existing method.

Sort of… overwriting an existing method that is _known_ about is one  
thing, but since this would potentially be over writing a method that is  
dynamically created (or handled by method\_missing) if and only if the  
model happens to have the right column name could make for a lot of head  
banging ☹

> A bit more searching revealed TextSearch  
> ([http://wiki.rubyonrails.org/rails/pages/TextSearch](http://wiki.rubyonrails.org/rails/pages/TextSearch)), which seems like a more  
> elegant solution in a lot of ways…

Oooh… that’s nice… maybe a variation/extension of that so you  
wouldn’t  
have to pick a set of columns, but could do a dynamic clone of say:

Model.search\_by\_surname

That removes any ambiguity… and lets you do  
Model.search\_by\_surname\_and\_first\_name

which would come in kind of handy 🙂

---

<div class="post-metadata">

**Author:** ![starmaerker](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9bcb4/32.png) [@starmaerker](https://www.ruby-forum.com/u/starmaerker)\
**Post date:** [January 18, 2007, 3:06am UTC](https://www.ruby-forum.com/t/find-by-like/82053/7 "2007-01-18T03:06:04Z")

</div>

Philip H. wrote:

> Oooh… that’s nice… maybe a variation/extension of that so you  
> wouldn’t  
> have to pick a set of columns, but could do a dynamic clone of say:
> 
> Model.search\_by\_surname
> 
> That removes any ambiguity… and lets you do  
> Model.search\_by\_surname\_and\_first\_name
> 
> which would come in kind of handy 🙂

Seems like a good idea and should be pretty easy to copy over the  
dynamic finder code and make any adjustments needed.

I will give it a go in the next week or two - a great way to learn is by  
trying to solve problems 🙂
