How to convert from a string to object attribute name?

前端 未结 2 1399
忘了有多久
忘了有多久 2020-12-15 06:02

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 co

相关标签:
2条回答
  • 2020-12-15 06:16

    Look at instance_eval method ...

    if you have 'attribute' and need do

     object.attribute = 'ololo'
    

    you can do:

    object.instance_eval('attribute') = 'ololo'
    
    0 讨论(0)
  • 2020-12-15 06:28

    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.

    0 讨论(0)
提交回复
热议问题