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

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

问题描述

我想为一个字符串值转换为属于一个对象的属性的名称。例如,在下面的code,我需要在 column_array 变成属性名称的所有字符串值。名称student_identification电子邮件等都是实际的列名我的学生表。在真实的情景, column_array 将被用户(通过勾选复选框)设置。和 new_array CSV 代替,因为我想要的数据进入一个CSV文件中。

目前,我真的很挣扎在以下行:

  new_array<<河#{column_array [I]}

我想#{column_array [I]}来变成属性的名称,所以我可以访问这些数据。

 高清exp_tst  @records = Student.find(:全部:条件=>会话[:selection_scope]
                                 :为了=> SORT_ORDER('laboratory_id'))  column_array = [student_identification,laboratory_id,电子邮件,CURRENT_STATUS]  new_array = Array.new()  @ records.each做| R |    (0 ..(column_array.size-1))每做|我|
       new_array<<河#{column_array [I]}
    结束
  结束结束


解决方案

比方说, column_array [I] =富的例子。

如果你想调用的方法 r.foo ,使用对象#发送

  r.send(column_array [I],ARG1,ARG2,ARG3,...)

如果您要访问的研究实例变量 @foo ,使用对象#instance_variable_get 对象#instance_variable_set

  r.instance_variable_get(@+ column_array [I])
 r.instance_variable_set(@+ column_array [I],NEW_VALUE)

在这种情况下,我们必须prePEND与 @ 印记给定的名字,因为这是需要在所有的实例变量名的开始。

由于这是铁轨,还有一大堆的的ActiveRecord 魔法与您的模型怎么回事(我猜学生的ActiveRecord :: Base的),你可能想使用前者,因为的ActiveRecord 创建的子类方法来访问数据库,并存储在实例变量中的值可能不是你想要的或期望的。

我将用一些测试数据我得躺在身边的例子:

 %脚本/控制台
加载开发环境(线路2.3.2)
IRB>顾客
#=>客户(ID:整数,date_subscribed:日期时间,rental_plan_id:整数,名称:字符串,地址:字符串,PHONE_NUMBER:字符串,CREDIT_LIMIT:小数,last_bill_end_date:日期时间,余额:十进制)
IRB> example_customer = Customer.find(:所有)[0]
#=> #<客户ID:6,date_subscribed:2007-12-24 05:00:00,rental_plan_id:3,名称:Evagation Governessy,地址:803 Asbestous圣,Uneradicated锡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,天平:#<的BigDecimal :191e870,'0.743E3',4(12)>>
IRB> example_customer.name
#=> Evagation Governessy
IRB>字段='名称'
#=> 名称
IRB> example_customer.instance_variable_get(场)
NameError:`name`不允许作为实例变量名
从(IRB):8:`instance_variable_get`
从(IRB):8
IRB> example_customer.instance_variable_get(@+字段)
#=>零
IRB> example_customer.send(场)
#=> Evagation Governessy
IRB> example_customer.send(字段+'=',Evagation Governessy小)
#=> Evagation Governessy小
IRB> example_customer.send(场)
#=> Evagation Governessy小
IRB> example_customer.name
#=> Evagation Governessy小

所以,你可以看到 #send(场)访问记录信息,并试图访问的属性没有。
此外,我们可以使用 #send(现场+'=')来改变记录信息。

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]}"

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

解决方案

Let's say column_array[i] = "foo", for an example.

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

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

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.

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."

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天全站免登陆