views:

60

answers:

3

Hey guys, busy learning ROR... I wasn't quite sure how to look for this problem on stackoverflow so sorry if this has been asked before :p

Basically I'm in the Console environment busy reading all the rows from a table into a variable and I noticed that you can reference the results by specifing my_object.id OR my_object[:id].

Can someone tell me if there is a specific reason for this? Is one of these 'methods' deprecated or what is the reason for this?

Here is a code snippit: (assuming all has been set)

my_object = MyModel.find(:all)
my_object[1].id #returns => 'my value'
my_object[1][:id] # also returns => 'my value'

Which of these methods are best practice? Or is it purely a notation preference?

Thanks :)

+1  A: 

It's a way of doing a read_attribute, which is protected, outside of the class. From the ActiveRecord::Base source code:

# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
# (Alias for the protected read_attribute method).
def [](attr_name)
  read_attribute(attr_name)
end

model.attribute is the most common way of doing it. The [] method obviously works well if the name of the attribute is stored in a variable.

neutrino
A: 
klochner
+1  A: 

you should use

my_object[1].id

"id" is an instance method generated by rails in the MyModel class and it has its corresponding "id=" setter instance method (yes, it's a method)

in the other hand

my_object[1][:id] or my_object[1]["id"] 

will access the @attributes hash directly:

    def read_attribute(attr_name)
      attr_name = attr_name.to_s
      if !(value = @attributes[attr_name]).nil?
      ......
    end

I'd like you to see this code

def [](attr_name)
   read_attribute(attr_name)
end

my_object[1][:id]

If you see the signature of the [] method maybe you'd think that you can call the method like this:

my_object[1][](:id)

but you can't do that because Ruby makes some trickery behind the scenes to make it appear just like if you were accessing a normal array (just like php, js, etc does it), don't get confused.

raf