Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dynamically get rails association

If I have an association name as a string, is there a way I can get a handle on the association object?

For example:

o = Order.first

o.customer will give me the customer object that this order belongs to.

If I have:

o = Order.first
relationship = 'customer'

i would like to do something like:

customer = eval("o.#{relationship}")

I know eval is a terrible option and I should avoid it. What is the best way to do this (as eval does not work in this example).

I did have this working:

customer = o.association(relationship)

I later found out that the association is not part of the public API and should not be used. Because when I took a line of code I had higher up the page off (that referenced that relationship) it stopped working.

Any ideas would be awesome!

like image 601
Sean Avatar asked Jul 02 '13 18:07

Sean


3 Answers

What about just doing this?

customer = o.send(relationship)
like image 176
mario Avatar answered Oct 13 '22 20:10

mario


You can use try() which will allow you manage any undefined method errors if the relationship doesn't exist.

relationship = 'customer'
foo = 'foo'

customer = o.try(relationship)
# > [
#     [0] #<Customer...

customer = o.try(foo)
# > nil

vs send():

customer = o.send(relationship)
# > [
#     [0] #<Customer... 

customer = o.send(foo)
# > NoMethodError: undefined method `foo' for #<Order...
like image 22
Eric Norcross Avatar answered Oct 13 '22 20:10

Eric Norcross


For those who fears using send:

o.association(relationship).scope
like image 4
lulalala Avatar answered Oct 13 '22 20:10

lulalala