如何从字符串转换为对象属性名称? [英] How to convert from a string to object attribute name?

查看:10
本文介绍了如何从字符串转换为对象属性名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将字符串值转换为属于对象的属性的名称.例如,在下面的代码中,我需要将 column_array 中的所有字符串值转换为属性名称."student_identification""email" 等名称是我的 Student 表的实际列名.在实际场景中,column_array 将由用户设置(通过勾选复选框).并且 new_array 将被 csv 替换,因为我希望数据进入 csv 文件.

I am trying to convert a string value into a name of an attribute that belongs to an object. For example, in the following code, I need all the string values in the column_array turned into attribute names. The names "student_identification", "email", etc. are actual column names of my Student table. In the real scenario, column_array will be set by the user (by ticking check boxes). And new_array will be replaced by csv, as I want the data go into a csv file.

目前我真的在以下行中苦苦挣扎:

At the moment I am really struggling at the following line:

   new_array << r."#{column_array[i]}"

我希望将 "#{column_array[i]}" 转换为属性名称,以便我可以访问数据.

I want "#{column_array[i]}" to be turned into the attribute name so I can access the data.

def exp_tst

  @records =  Student.find(:all, :conditions=> session[:selection_scope],
                                 :order => sort_order('laboratory_id'))

  column_array = ["student_identification", "laboratory_id", "email", "current_status"]

  new_array = Array.new()

  @records.each do |r|

    (0..(column_array.size-1)).each do |i|
       new_array << r."#{column_array[i]}"
    end
  end

end

推荐答案

比如column_array[i] = "foo".

如果要调用方法 r.foo,请使用Object#send:

If you want to call the method r.foo, use Object#send:

 r.send(column_array[i], arg1, arg2, arg3, ...)

如果要访问r的实例变量@foo,使用Object#instance_variable_getObject#instance_variable_set:

If you want to access r's instance variable @foo, use Object#instance_variable_get and Object#instance_variable_set:

 r.instance_variable_get('@'+column_array[i])
 r.instance_variable_set('@'+column_array[i], new_value)

在这种情况下,我们必须在给定名称前加上 @ 印记,因为这是所有实例变量名称的开头所必需的.

In this case we have to prepend the given name with an @ sigil, since that is required at the start of all instance variable names.

因为这是 rails,你的模型有很多 ActiveRecord 魔法(我猜 StudentActiveRecord 的子类::Base) 您可能希望使用前者,因为 ActiveRecord 创建了访问数据库的方法,而存储在实例变量中的值可能不是您想要或期望的.

Since this is rails, and there's a whole lot of ActiveRecord magic going on with your models (and I'm guessing Student is a subclass of ActiveRecord::Base) you probably want to use the former, since ActiveRecord creates methods to access the database, and the values stored in instance variables may not be what you want or expect.

我将使用我得到的一些测试数据中的一个示例:

I'll use an example from some test data I've got lying around:

% script/console
Loading development environment (Rails 2.3.2)
irb> Customer
#=> Customer(id: integer, date_subscribed: datetime, rental_plan_id: integer, name: string, address: string, phone_number: string, credit_limit: decimal, last_bill_end_date: datetime, balance: decimal)
irb> example_customer = Customer.find(:all)[0]
#=> #<Customer id: 6, date_subscribed: "2007-12-24 05:00:00", rental_plan_id: 3, name: "Evagation Governessy", address: "803 Asbestous St, Uneradicated Stannous MP 37441", phone_number: "(433) 462-3416", credit_limit: #<BigDecimal:191edc0,'0.732E3',4(12)>, last_bill_end_date: "2009-05-15 04:00:00", balance: #<BigDecimal:191e870,'0.743E3',4(12)>>
irb> example_customer.name
#=> "Evagation Governessy"
irb> field = 'name'
#=> "name"
irb> example_customer.instance_variable_get(field)
NameError: `name` is not allowed as an instance variable name
from (irb):8:in `instance_variable_get`
from (irb):8
irb> example_customer.instance_variable_get('@'+field)
#=> nil
irb> example_customer.send(field)
#=> "Evagation Governessy"
irb> example_customer.send(field+'=', "Evagation Governessy Jr.")
#=> "Evagation Governessy Jr."
irb> example_customer.send(field)
#=> "Evagation Governessy Jr."
irb> example_customer.name
#=> "Evagation Governessy Jr."

因此您可以看到 #send(field) 如何访问记录信息,而尝试访问属性则不会.另外,我们可以使用#send(field+'=')来改变记录信息.

So you can see how #send(field) accesses the record information, and trying to access the attributes doesn't. Also, we can use #send(field+'=') to change record information.

这篇关于如何从字符串转换为对象属性名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆