2009-05-24 13 views
18

Sto provando a convertire un valore stringa in un nome di un attributo che appartiene a un oggetto. Ad esempio, nel seguente codice, ho bisogno che tutti i valori di stringa in column_array diventino nomi di attributi. I nomi "student_identification", "email", ecc. Sono i nomi effettivi delle colonne della tabella Student. Nello scenario reale, column_array verrà impostato dall'utente (barrando le caselle di controllo). E new_array sarà sostituito da csv, poiché voglio che i dati vadano in un file csv.Come convertire da stringa ad oggetto nome attributo?

Al momento sto davvero lottando alla seguente riga:

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

voglio "#{column_array[i]}" per essere trasformato nel nome dell'attributo in modo da poter accedere ai dati.

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)). Each' può essere sostituito con 'column_array.each_index'. –

risposta

39

Diciamo column_array[i] = "foo", per un esempio.

Se si desidera chiamare il metodo r.foo, utilizzare Object#send:

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

Se si desidera accedere r s' istanza variabile @foo, utilizzare Object#instance_variable_get e Object#instance_variable_set:

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

In In questo caso dobbiamo anteporre il nome dato a un sigillo @, poiché è necessario inizio di tutti i nomi delle variabili di istanza.

poiché questo è rotaie, e c'è un sacco di ActiveRecord magia succedendo con i vostri modelli (e sto cercando di indovinare Student è una sottoclasse di ActiveRecord::Base) probabilmente si desidera utilizzare il primo, dal momento che ActiveRecord crea metodi per accedere alla database e i valori memorizzati nelle variabili di istanza potrebbero non essere ciò che si desidera o si aspetta.

userò un esempio da alcuni dati di test che ho ottenuto in giro:

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

Così si può vedere come #send(field) accede le informazioni del record, e cercando di accedere agli attributi non. Inoltre, è possibile utilizzare #send(field+'=') per modificare le informazioni del record.

+0

Hi, sì Lo studente è sottoclasse di 'ActiveRecord :: Base' classe Student Vicer

+1

È possibile accedere ai contenuti delle colonne tramite i metodi di accesso in ActiveRecord. Non esiste il concetto di "solo nomi di colonne" in Ruby. – Chuck

+0

Ciao, Solo per rendere il problema un po 'più avanzato .. diciamo che l'oggetto' example_customer 'ha un metodo chiamato' get_details_of_membership ('membership_type') '. Qui 'membership_type' può essere 'platinum', 'annual', 'monthly' ecc. Ma se ho usato questo comando: example_customer.send ('get_details_of_membership (' platinum ')') , non lo farà lavoro. in realtà mi desidera memorizzare il 'get_details_of_membership stringa (' platinum ')' in una variabile del tipo: campo = 'get_details_of_membership (' platinum ')' e poi fare: example_customer.send (campo) Can qualcuno mostrami un modo per affrontare questo? – Vicer

4

sguardo al metodo instance_eval ...

se avete 'attributo' e bisogno di fare

object.attribute = 'ololo' 

si può fare:

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