2009-05-24 51 views
18

Tôi đang cố chuyển đổi một giá trị chuỗi thành tên thuộc tính thuộc về một đối tượng. Ví dụ, trong đoạn mã sau, tôi cần tất cả các giá trị chuỗi trong các column_array biến thành tên thuộc tính. Tên "student_identification", "email", v.v ... là tên cột thực tế của bảng Student của tôi. Trong trường hợp thực tế, column_array sẽ được đặt bởi người dùng (bằng cách đánh dấu vào các hộp kiểm). Và new_array sẽ được thay thế bằng csv, vì tôi muốn dữ liệu đi vào tệp csv.Làm thế nào để chuyển đổi từ một chuỗi thành tên thuộc tính đối tượng?

Tại thời điểm tôi đang thực sự gặp khó khăn tại các dòng sau:

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

Tôi muốn "#{column_array[i]}" được biến thành tên thuộc tính để tôi có thể truy cập dữ liệu.

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 
+0

'(0 .. (column_array.size -1)) mỗi 'có thể được thay thế bằng' column_array.each_index'. –

Trả lời

39

Giả sử column_array[i] = "foo", ví dụ:

Nếu bạn muốn gọi phương thức r.foo, sử dụng Object#send:

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

Nếu bạn muốn truy cập r 's dụ biến @foo, sử dụng Object#instance_variable_getObject#instance_variable_set:

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

Trong trường hợp này, chúng ta phải thêm vào tên đã cho với một sigil @, vì nó được yêu cầu tại bắt đầu của tất cả các tên biến mẫu.

Do đây là đường ray, và có rất nhiều toàn bộ ActiveRecord kỳ diệu xảy ra với mô hình của bạn (và tôi đoán Student là một lớp con của ActiveRecord::Base), bạn có thể muốn sử dụng trước đây, kể từ khi ActiveRecord tạo ra phương pháp để truy cập cơ sở dữ liệu và các giá trị được lưu trữ trong các biến mẫu có thể không phải là những gì bạn muốn hoặc mong đợi.

tôi sẽ sử dụng một ví dụ từ một số dữ liệu thử nghiệm tôi đã bị nằm xung quanh:

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

Vì vậy, bạn có thể thấy cách #send(field) truy cập vào thông tin hồ sơ, và cố gắng để truy cập vào các thuộc tính không. Ngoài ra, chúng tôi có thể sử dụng #send(field+'=') để thay đổi thông tin hồ sơ.

+0

Xin chào, yes Sinh viên là lớp con của 'ActiveRecord :: Base' Học sinh lớp Vicer

+1

Bạn truy cập nội dung của các cột thông qua các phương thức truy cập trong ActiveRecord. Không có khái niệm "chỉ tên cột" trong Ruby. – Chuck

+0

Xin chào, Chỉ để thực hiện vấn đề cao hơn một chút .. giả sử đối tượng 'example_customer' của bạn có phương thức được gọi là 'get_details_of_membership (' membership_type ')'. Ở đây 'member_type' có thể là 'platinum', 'hàng năm', 'hàng tháng', v.v. Nhưng nếu tôi sử dụng lệnh này: example_customer.send ('get_details_of_membership (' platinum ')') , nó sẽ không công việc. thực sự tôi muốn để lưu trữ các chuỗi 'get_details_of_membership (' bạch kim ')' trong một biến như: lĩnh vực = 'get_details_of_membership (' bạch kim ')' và sau đó làm: example_customer.send (field) Có thể ai đó chỉ cho tôi một cách để giải quyết vấn đề này? – Vicer

4

Nhìn vào phương pháp instance_eval ...

nếu bạn có 'thuộc tính' và cần làm

object.attribute = 'ololo' 

bạn có thể làm:

object.instance_eval('attribute') = 'ololo' 
Các vấn đề liên quan