Руби Эвал рефакторинг - PullRequest
       13

Руби Эвал рефакторинг

0 голосов
/ 12 декабря 2011

У меня есть такие модели:

Class User
  has_many :comments
  # have field 'name' in DB
end

Class Comment
  belongs_to :user
end

И у меня очень сложный и очень сложный для понимания бэкэнд администратора, который получает все модели и позволяет управлять им из интерфейса администратора.Он получает все ассоциации и обрабатывает его с помощью evals.

И такой eval отлично работает:

eval("comment." + o[0][:object])

, где o [0] [: object] = "user.name"

Но я хочу сделать это без Eval.Этот подход работает, но он не очень универсален:

comment.send("user").send("name")

И в реальном коде он выглядит очень некрасиво:

(o[0][:object].split(".").count < 2) ? h(object.send(o[0][:object])) : h(object.send(o[0][:object].split(".")[0]).send(o[0][:object].split(".")[1]))

Итак, каков наилучший способ получить универсальность eval для таких конструкций?, если я хочу показать больше вложенных вызовов, например:

comment.user.first_friend.haters.count

???

Ответы [ 2 ]

2 голосов
/ 12 декабря 2011

Я не уверен, почему вы не хотите использовать eval в этом случае.Иногда это лучшее решение.

Здесь вы можете сделать это просто:

o[0][:object].split('.').reduce(object){|method, obj| obj.send method }
0 голосов
/ 12 декабря 2011

А что по этому поводу?

class Object # or just ActiveRecord::Base
  def multiple_send(methods)
    first_method, remaining_methods = methods.split(".", 2)
    ret = __send__(first_method) # I use __send__ to prevent from classes overwriting send() method

    remaining_methods.nil? ? ret : ret.multiple_send(remaining_methods)
  end
end

Тогда вы можете написать что-то вроде comment.multiple_send("user.name").

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...