Rails 5动态添加非持久性ActiveRecord属性

时间:2019-04-12 13:33:15

标签: ruby-on-rails ruby-on-rails-5 rails-activerecord

我有一个要升级到Rails 5的Rails 2.3应用程序。

在我的某些模型中,存在非持久性属性,我可以通过以下方式在控制器中进行读写:

  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 :(得分:0)

虽然我确定还有更多的ActiveModelRoR GuidesAPI-但这可能不是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 /");"或其他有害代码!