views:

232

answers:

3

This is how to convert a string to a class in Rails/Ruby:

p = "Post"
Kernel.const_get(p)
eval(p)
p.constantize

But what if I am retrieving a column from an array/active record object like:

Post.description

but it could be

Post.anything

where anything is a string like anything = "description"

How can I make it work? Any ideas. This is helpful since I want to refactor a very large class and reduce lines of code and repetition.

Many thanks.

+7  A: 
Post.send(anything)
shingara
working perfectly, thanks. reduced so many lines of code to just a few.
kgpdeveloper
So you can accept answer.
shingara
+2  A: 

While eval can be a useful tool for this sort of thing, and those from other backgrounds may take to using it as often as one might a can opener, it's actually dangerous to use so casually. Eval implies that anything can happen if you're not careful.

A safer method is this:

on_class = "Post"
on_class.constantize.send("method_name")
on_class.constantize.send("method_name", arg1)

Object#send will call whatever method you want. You can send either a Symbol or a String and provided the method isn't private or protected, should work.

tadman
This is already executing arbitrary methods. Security doesn't seem to be a major factor here.
Chuck
Arbitrary methods are a lot different from arbitrary code. I doubt you have a "DROP ALL TABLES" method on your class. It's also elementary to verify that a given string is safe or not to use as a method name, you can have a simple white-list to check, however evaluating the danger of an arbitrary eval block is impossible.
tadman
A: 

Hi

try this

class Test def method_missing(id, *args) puts id - get your method name puts args - get values
end end

a = Test.new a.name('123')

so the general syntax would be a.()

hope this helps

cheers

sameera

sameera207