Динамически получить рельсы ассоциации

Если у меня есть имя ассоциации в виде строки, есть ли способ получить дескриптор объекта ассоциации?

Например:

o = Order.first

o.customer даст мне объект клиента, которому принадлежит этот заказ.

Если у меня есть:

o = Order.first
relationship = 'customer'

я хотел бы сделать что-то вроде:

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

Я знаю, что eval - ужасный вариант, и я должен избегать его. Каков наилучший способ сделать это (поскольку eval не работает в этом примере).

У меня было это работает:

customer = o.association(relationship)

Позже я обнаружил, что ассоциация не является частью публичного API и не должна использоваться. Потому что, когда я взял строку кода, я поднял страницу вверх (которая ссылалась на эти отношения), она перестала работать.

Любые идеи будут потрясающими!

2 ответа

Решение

Как насчет просто сделать это?

customer = o.send(relationship)

Для тех, кто боится использовать send:

o.association(relationship).scope

Ты можешь использовать try() который позволит вам управлять любым undefined method ошибки, если отношения не существуют.

relationship = 'customer'
foo = 'foo'

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

customer = o.try(foo)
# > nil

против send():

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

customer = o.send(foo)
# > NoMethodError: undefined method `foo' for #<Order...
Другие вопросы по тегам