Rails 5 динамически добавляет непостоянные атрибуты ActiveRecord - PullRequest
0 голосов
/ 12 апреля 2019

У меня есть приложение Rails 2.3, которое я хочу обновить до Rails 5.

В некоторых моих моделях есть непостоянные атрибуты, я могу читать и писать в моем контроллере следующим образом:

  r_v = Model.new
  r_v[:count_all_bqu] = 0
  r_v[:count_all_bsk] = 0
  r_v[:count_all_bmd] = 0

Я изменил структуру, потому что по какой-то причине Rails 5 больше не обрабатывает ее.

Итак, я создал attr_accessors в моей модели:

  attr_accessor :count_all_bqu
  attr_accessor :count_all_bsk
  attr_accessor :count_all_bmd

и заменил строки выше на следующие:

  r_v = Model.new
  r_v.count_all_bqu = 0
  r_v.count_all_bsk = 0
  r_v.count_all_bmd = 0  

Пока проблем нет.

Но есть и такие вещи, как:

  for r in Model.where(condition)
    r_v["count_#{r.b_id}_erg_bst"] = 0
    ...

Как преобразовать "count _ # {r.b_id} _erg_bst" в непостоянный атрибут?

1 Ответ

0 голосов
/ 19 апреля 2019

Хотя я уверен, что есть более ActiveModel ( RoR Guides , API - но это может быть не ActiveModel, а аналогичный модуль) способ сделать это,с простым Ruby вы бы сделали это следующим образом:

r_v.send("count_#{r.b_id}_erg_bst=", 0)

По сути, вы «вызываете» метод count_..._erg...= (метод, назначающий локальную переменную, определенную attr_accessor) с аргументом 0.

Для r.bid == 'my' это будет то же самое, что и вызов r_v.count_my_erg_bst= 0.

Обратите внимание, что это будет работать, только если что-то вроде attr_accessor :count_my_erg_bst является частью определения вашего класса.

В противном случае вы можете сделать это более метапрограммирующим, например, rv.instance_eval { @count_my_erg_bst = 0 } или потому, что вам нужна интерполяция строк rv.instance_eval " @count_#{r.bid}_erg_bst = 0 "

Обратите внимание на последствия для безопасности! Если r.bidпредоставляется пользователем, это может быть что-то вроде "a = 1; system("rm -rf /");" или другой вредоносный код!

...