Динамически получить рельсы ассоциации
Если у меня есть имя ассоциации в виде строки, есть ли способ получить дескриптор объекта ассоциации?
Например:
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...