# Active record associations

**URL:** <https://www.ruby-forum.com/t/active-record-associations/152664>\
**Category:** Rails\
**Created:** [November 6, 2008, 5:39am UTC](https://www.ruby-forum.com/t/active-record-associations/152664 "2008-11-06T05:39:31Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![obenhauser](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/d78d45/32.png) [@obenhauser](https://www.ruby-forum.com/u/obenhauser)\
**Post date:** [November 6, 2008, 5:39am UTC](https://www.ruby-forum.com/t/active-record-associations/152664/1 "2008-11-06T05:39:31Z")

</div>

I want to accomplish the following. I have an object that can be  
edited. However, it can occur that two people might edit the object  
at the same time. Instead of locking the object down, I prefer to  
tell the user how their version differs from the last version that was  
committed.

Kinda like:

respond\_to do |format|  
@document = Document.find\_by\_id(1)  
@document.attributes = params[:document]  
@changes = @document.diff(Document.find\_by\_id(1))  
format.html { render :action =\> “edit” }  
end

The edit screen then renders the changes for the user to compare. The  
user can then apply some changes or ignore the changes and save.

This works fine for regular fields, but when the object has has\_many  
assoctiations, then the following would occur.

respond\_to do |format|  
@document = Document.find\_by\_id(1)  
@document.attributes = params[:document] # =\> this call would  
update the database for all has\_many associations  
@changes = @document.diff(Document.find\_by\_id(1)) #=\> retrieving  
the previous object state from the database is not possible since the  
associations have changed  
format.html { render :action =\> “edit” }  
end

I also tried to compare the object to the attributes kinda like this;

respond\_to do |format|  
@document = Document.find\_by\_id(1)  
@changes = @document.diff(params[:document])  
format.html { render :action =\> “edit” }  
end

But then the user’s changes aren’t stored on the object and all  
updates are lost.

Any help is appreciated.

---

<div class="post-metadata">

**Author:** ![obenhauser](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/d78d45/32.png) [@obenhauser](https://www.ruby-forum.com/u/obenhauser)\
**Post date:** [November 6, 2008, 5:55pm UTC](https://www.ruby-forum.com/t/active-record-associations/152664/2 "2008-11-06T17:55:22Z")

</div>

This sounds like the dirty object feature of Rails 2.1 would work  
great:  
[http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects](http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects)

Maybe even try to utilize some callback methods so you can capture and  
display the changes to the user:  
[http://railsforum.com/viewtopic.php?id=23001](http://railsforum.com/viewtopic.php?id=23001)

---

<div class="post-metadata">

**Author:** ![obenhauser](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/d78d45/32.png) [@obenhauser](https://www.ruby-forum.com/u/obenhauser)\
**Post date:** [November 7, 2008, 4:18am UTC](https://www.ruby-forum.com/t/active-record-associations/152664/3 "2008-11-07T04:18:59Z")

</div>

The dirty object feature doesn’t work for has\_many associations. I  
solved the problem by wrapping a transaction around the code to revert  
the changes in the database. I kinda wish, ror could keep the  
functionality between regular fields and association fields consistent  
to avoid confusion.

kinda like:

class Person  
has\_many :cars  
end

> > person = Person.find\_by\_name(“Jack”)  
> > person.cars  
> > =\> [#\<Car id: 2, name: “BMW”, created\_at: “2008-11-04 03:04:46”,  
> > updated\_at: “2008-11-04 03:04:46”\>]
> 
> > person.cars=[Car.find\_by\_name(“Porsche”), Car.find\_by\_name(“VW”)]  
> > person.cars  
> > =\> [#\<Car id: 1, name: “Porsche”, created\_at: “2008-11-04 03:04:46”,  
> > updated\_at: “2008-11-04 03:04:46”\>, #\<Car id: 3, name: “VW”,  
> > created\_at: “2008-11-04 03:04:46”, updated\_at: “2008-11-04 03:04:46”\>]
> 
> > person.changed?  
> > =\> true
> 
> > person.changes  
> > =\> {“cars”=\>[[#\<Car id: 2, name: “BMW”, created\_at: “2008-11-04  
> > 03:04:46”, updated\_at: “2008-11-04 03:04:46”\>], [#\<Car id: 1, name:  
> > “Porsche”, created\_at: “2008-11-04 03:04:46”, updated\_at: “2008-11-04  
> > 03:04:46”\>, #\<Car id: 3, name: “VW”, created\_at: “2008-11-04  
> > 03:04:46”, updated\_at: “2008-11-04 03:04:46”\>]]}
> 
> > person.save #associations are saved in the database

However ror returns the following

> > person = Person.find\_by\_name(“Jack”)  
> > person.cars  
> > =\> [#\<Car id: 2, name: “BMW”, created\_at: “2008-11-04 03:04:46”,  
> > updated\_at: “2008-11-04 03:04:46”\>]
> 
> > person.cars=[Car.find\_by\_name(“Porsche”), Car.find\_by\_name(“VW”)] #associations are saved in the database  
> > person.cars  
> > =\> [#\<Car id: 1, name: “Porsche”, created\_at: “2008-11-04 03:04:46”,  
> > updated\_at: “2008-11-04 03:04:46”\>, #\<Car id: 3, name: “VW”,  
> > created\_at: “2008-11-04 03:04:46”, updated\_at: “2008-11-04 03:04:46”\>]
> 
> > person.changed?  
> > =\> false
> 
> > person.changes  
> > =\> {}
