[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

still more relentless non-repetition

Giles Bowkett

10/31/2006 11:26:00 PM

ok, I have this Rails code which I want to make more Rubyish.

controller:

def tracks
@term = params[:term] || ''
if @term.blank?
@tracks = []
else
@tracks = Track.find_by_contents @term
end
end

view:

<% for word in %w{ tracks beats users profiles } %>

<% unless controller.action_name == word %>
<%= link_to "search similar #{word}", :action => word, :term => @term %>
<br/>
<% end %>

<% end %>

now this is using Ferret, the Ruby port of Lucene, via the
acts_as_ferret Rails plugin.

(by the way, Ferret actually runs faster than Lucene, according to the
Ferret site. I don't know how, but that's pretty cool.)

anyway, as you can see, I have one method in the controller and a view
which assumes the existence of three additional methods.

what I want to do is have only one method in the controller, which
does all the searching.

now I could do:

def tracks
@term = params[:term] || ''
case params[:thing_to_search_for]
when "tracks"
if @term.blank?
@tracks = []
else
@tracks = Track.find_by_contents @term
end
when "beats"
if @term.blank?
@beats = []
else
@beats = Beat.find_by_contents @term
end
when "profiles"
if @term.blank?
@profiles = []
else
@profiles = Profile.find_by_contents @term
end
when "users"
if @term.blank?
@users = []
else
@users = User.find_by_contents @term
end
end
end

however, this is what Rails users call "wet" and everybody else calls "stupid."

what I want to do is a properly elegant thingy. here's roughly what I envision:

def search
@term = params[:term] || ''
instance_variable_set("@#{params[:thing_to_search_for]}", [])
unless @term.blank?
eval("@#{params[:thing_to_search_for]}") =
(eval(params[:thing_to_search_for].capitalize)).find_by_contents @term
end
end

I think I should probably just start coding in Lisp and save everyone
the irritation, but in the meantime, how does that look, in terms of a
tree to bark up? that is to say, does it look like the right tree, or
the wrong tree?

if you can puzzle it through, I think what I have here is an elegant
algorithm expressed in very-much-other-than-elegant code. (but I could
be wrong!)

--
Giles Bowkett
http://www.gilesg...

13 Answers

Devin Mullins

10/31/2006 11:37:00 PM

0

I'm too lazy ATM to read the whole thing and make a design
recommendation, but Danger, Will Robinson!
> eval("@#{params[:thing_to_search_for]}") =
> (eval(params[:thing_to_search_for].capitalize)).find_by_contents @term
Major Ruby-injection problem here. NEVER eval something you get from an
untrusted user. Use, instead, instance_variable_get and Object.const_get.

Devin

Giles Bowkett

10/31/2006 11:55:00 PM

0

ah yeah, that's a good point, SQL injection attacks.

On 10/31/06, Devin Mullins <twifkak@comcast.net> wrote:
> I'm too lazy ATM to read the whole thing and make a design
> recommendation, but Danger, Will Robinson!
> > eval("@#{params[:thing_to_search_for]}") =
> > (eval(params[:thing_to_search_for].capitalize)).find_by_contents @term
> Major Ruby-injection problem here. NEVER eval something you get from an
> untrusted user. Use, instead, instance_variable_get and Object.const_get.
>
> Devin
>
>


--
Giles Bowkett
http://www.gilesg...

dblack

11/1/2006 12:11:00 AM

0

Ara.T.Howard

11/1/2006 12:16:00 AM

0

Giles Bowkett

11/1/2006 12:46:00 AM

0

> >> Major Ruby-injection problem here. NEVER eval something you get from an
> >> untrusted user. Use, instead, instance_variable_get and Object.const_get.
> >
> > ah yeah, that's a good point, SQL injection attacks.
>
> It's not so much SQL injection as eval injection. Imagine if
> params[:thing_to_search_for] is "a=1; system('rm -rf /*')" or
> something. You'd be eval'ing the string:
>
> @a=1; system('rm -rf /*')

true, that would also be very bad.

--
Giles Bowkett
http://www.gilesg...

Giles Bowkett

11/1/2006 12:48:00 AM

0

> model = self.class.const_get t.capitalize
> model.find_by_contents t

**that** looks like the way to do it.

gracias!

--
Giles Bowkett
http://www.gilesg...

dblack

11/1/2006 1:25:00 AM

0

Ara.T.Howard

11/1/2006 2:04:00 AM

0

Wilson Bilkovich

11/1/2006 3:26:00 AM

0

On 10/31/06, Giles Bowkett <gilesb@gmail.com> wrote:
> > model = self.class.const_get t.capitalize
> > model.find_by_contents t
>
> **that** looks like the way to do it.
>
> gracias!
>

ActiveSupport has a helper for this already.

model = t.constantize
model.find_by_contents(t)

Giles Bowkett

11/1/2006 5:31:00 AM

0

wow that's handy:

thing.constantize.find_by_contents(term)

boom! done.

On 10/31/06, Wilson Bilkovich <wilsonb@gmail.com> wrote:
> On 10/31/06, Giles Bowkett <gilesb@gmail.com> wrote:
> > > model = self.class.const_get t.capitalize
> > > model.find_by_contents t
> >
> > **that** looks like the way to do it.
> >
> > gracias!
> >
>
> ActiveSupport has a helper for this already.
>
> model = t.constantize
> model.find_by_contents(t)
>
>


--
Giles Bowkett
http://www.gilesg...