如何从字符串转换为对象属性名称?

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

目前我真的在以下方面苦苦挣扎:

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

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

 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

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

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

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

在这种情况下,我们必须在@ sigil前面添加给定的名称,因为在所有实例变量名称的开头都需要它。

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

我将使用我所处理的一些测试数据中的示例:

 % 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] #=> #, last_bill_end_date: "2009-05-15 04:00:00", balance: #> 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+'=')来更改记录信息。

看看instance_eval方法……

如果你有“属性”并且需要做

  object.attribute = 'ololo' 

你可以做:

 object.instance_eval('attribute') = 'ololo'