# Model Versioning Plugin?

**URL:** <https://www.ruby-forum.com/t/model-versioning-plugin/141533>\
**Category:** Rails\
**Created:** [June 26, 2008, 8:29pm UTC](https://www.ruby-forum.com/t/model-versioning-plugin/141533 "2008-06-26T20:29:43Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 26, 2008, 8:29pm UTC](https://www.ruby-forum.com/t/model-versioning-plugin/141533/1 "2008-06-26T20:29:43Z")

</div>

Hi Everyone,

I am attempting to version my model, so I can go back through time, as  
well as offer an audit trail.

I have attempted to use acts\_as\_versioned ([http://wiki.rubyonrails.org/](http://wiki.rubyonrails.org/)  
rails/pages/ActsAsVersioned), but the issue with this is the  
associated models, which it does not support.

Here is an example of what my model looks like:

company has\_many phone\_numbers  
company has\_many contacts  
company has\_one status  
… and so on

I need to be able to have the plugin version each associated model  
automatically.

Does anyone know of a solution for this?

Thanks for your help!

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 26, 2008, 10:57pm UTC](https://www.ruby-forum.com/t/model-versioning-plugin/141533/2 "2008-06-26T22:57:23Z")

</div>

Lundie wrote:

> Hi Everyone,

> company has\_many phone\_numbers  
> company has\_many contacts  
> company has\_one status  
> … and so on
> 
> I need to be able to have the plugin version each associated model  
> automatically.
> 
> Does anyone know of a solution for this?

I haven’t heard of anything like that.

But I can’t imagine you can adapt ActsAsVersioned to your needs,  
because it works with a different table, so associations are going to  
break.

Perhaps a more bespoke solution;

add\_column :companies, :versioned\_at, :datetime, :default =\> nil  
add\_column :companies, :version\_of, :integer, :default =\> nil

Now when we “version” it, we go.

class Company

has\_many :versions, :class\_name =\> “Company”, :foreign\_key =\>  
“version\_id”, :order =\> “companies.versioned\_at DESC”  
belongs\_to :version\_of, :class\_name =\> “Company”

def version!  
transaction do  
versioned = Company.new(self.attributes.merge(:versioned\_at =\>  
Time.now, :version\_of =\> self.id)  
# go through each association and clone the attribs, pointing at  
versioned

```
  self.phone_numbers.each do |phone_number|
    versioned.phone_numbers.build(phone_number.attributes)
  end
  ...

  self.save!
end

```

end  
end

something like that maybe?  
(totally untested code)

Matthew R. Jacobs  
[http://funchforlunch.blogspot.com](http://funchforlunch.blogspot.com)

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [June 26, 2008, 11:00pm UTC](https://www.ruby-forum.com/t/model-versioning-plugin/141533/3 "2008-06-26T23:00:00Z")

</div>

Matthew R. Jacobs wrote:

> add\_column :companies, :versioned\_at, :datetime, :default =\> nil  
> add\_column :companies, :version\_of, :integer, :default =\> nil

and, if you did this,  
you’d have to remember only to look at “live versions”

class Company  
named\_scope :live, :conditions =\> {:version\_of =\> nil}  
end

and then always refer to;

Company.live.find(params[:id])
