in Projects, Programming, Technology

Rails ActiveRecord Tips

Ruby on Rails
Image via Wikipedia

After using ActiveRecord for a while, some questions keep coming up when performing operations that are more complicated than the standard create, read, update, delete.

1. Does ActiveRecord track if an attribute is has been modified? Does it track dirty state on an object or attribute basis?

Yes, but not for attributes so far as I can tell. Rails provides these great helper methods (examples given for a person sample object).

person.new_record?
person.changed?
person.name_changed?
person.name_was
person.name = 'bob'
person.changed        # => ['name']
person.changes        # => { 'name' => ['Bill', 'bob'] }

Documentation on Rails ActiveRecord dirty state methods

note that changed? does not capture if a collection has changed (nor seem to work for a collection)

2. Does ActiveRecord automatically set the reference pointers on both sides of a has_many relationship?

Surprisingly, no. For example

p = Person.new
e = EmailAddress.new
e.person = p
p. email_addresses # => []

even though EmailAddress belongs_to :person

the reverse is also true

e2 = EmailAddress.new
p.email_addresses.push(e2)
e2.entity # => nil

Also, this is the case even if p and e have been previously saved to the database.

3. Are objects automatically persisted when you insert into a collection?

Yes. From the documentation: “Adding an object to a collection (has_many or has_and_belongs_to_many) automatically saves that object, except if the parent object (the owner of the collection) is not yet stored in the database.”

You can add an object to a collection without automatically saving it by using the my_collection.build method

4. How does it handle database sessions, is there support for transactions?

I don’t see any support for sessions (in the “Hibernate” sense, where you can make a number of object changes, then dump those to the database all at once). However, simple transactions are definitely supported.

ActiveRecord::Base.transaction do
  david.withdrawal(100)
  mary.deposit(100)
end

Write a Comment

Comment