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

问题描述 投票:0回答:1

我有一个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”转换为非persitent属性?

ruby-on-rails ruby-on-rails-5 rails-activerecord
1个回答
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 /");"或其他有害代码!

© www.soinside.com 2019 - 2024. All rights reserved.