stephenmurdoch
stephenmurdoch

Reputation: 34613

Ruby instance variables versus ActiveRecord attributes

I've read that ruby objects are just places where we can store instance variables (and class pointers). So:

class Person
  def initialize(age)
    @age = age
  end
end

Now if we run:

p = Person.new(101)

Then we get:

#<Person:0x86cf5b8 @age=101>

Great, the property age is stored as an instance variable, as expected. But things work a little differently if we convert the model to inherit from ActiveRecord. Now, after instantiating an new Person, we see this:

# timestamps removed
#<Person id: 1, age: 101 > 

The age property no longer appears to be an instance variable. So what is really going on here?

I know that we can access the @attributes instance variable, which contains a hash of all the properties and values, so I'm wondering if ActiveRecord is possibly modifying the console output to present the objects attributes in this way.

Is it possible to instantiate a Ruby object where properties are held as attributes and not instance variables, without using ActiveRecord?

Upvotes: 5

Views: 6088

Answers (3)

D-side
D-side

Reputation: 9485

I'm wondering if ActiveRecord is possibly modifying the console output to present the objects attributes in this way.

Well, kind of. The method responsible for that is inspect, and it's implemented by Object in a way that (emplasis mine):

...shows the object's class name, an encoding of the object id, and a list of the instance variables and their values (by calling inspect on each of them).

There's more right after:

User defined classes should override this method to provide a better representation of obj.

This is exactly what ActiveRecord does and the reason why you're seeing this output. The overridden method does not list instance variables, but displays AR attributes.

So just because you aren't seeing the instance variable in the console doesn't mean it isn't there!

Upvotes: 0

seanreads
seanreads

Reputation: 448

Yes, you can extend a ruby class with include ActiveModel::AttributeMethods to expose your instance variables as ActiveModel-like attributes.

See the docs for more information.

Upvotes: 3

Viktor Tr&#243;n
Viktor Tr&#243;n

Reputation: 8884

as you see in your code 'storing' properties as instance vars was your own doing, so if you wanna hold them any other way, is also up to you. ruby gives you convenience class methods to define getter and setter methods like attr_accessor.

also worth noting, that if you inherit from ActiveRecord::Base, you should not override initialize.

Upvotes: 1

Related Questions