# Versioning the contents of a table as a set

**URL:** <https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427>\
**Category:** Rails\
**Created:** [May 3, 2006, 7:05pm UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427 "2006-05-03T19:05:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Eden\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/6de8d8/32.png) [@Eden\_B](https://www.ruby-forum.com/u/Eden_B)\
**Post date:** [May 3, 2006, 7:05pm UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427/1 "2006-05-03T19:05:37Z")

</div>

I am looking at using acts\_as\_versioned to manage revisions of data in  
several tables in my application. However, the default behavior of  
acts\_as\_versioned appears to apply to individual rows within a table.  
The  
tables I want to version are complicated lookup tables and what I really  
want is to version the entire contents of each table as a single set.  
Adding a row, deleting a row, or updating one or more rows should update  
the  
version of all rows. Is there a way to use acts\_as\_versioned to  
accomplish  
this? Is there a different approach that anyone can recommend?

The second part of this question stems from a bit of self-doubt as to  
whether I took a sensible approach with these tables. Essentially what  
I  
have is the following table (c1…c3 represent criteria, r represents  
result)  
for each set of criteria:

## r c1 c2 c3

1 1 1 1  
1 1 1 0  
0 1 0 1  
1 1 0 0  
0 0 1 1  
0 0 1 0  
0 0 0 1  
0 0 0 0

This allows me to select a result as follows myresult =  
mylookup.find(:conditions  
=\> [“c1 = ?”, “c2 = ?”, “c3 = ?”, a, b, c]).r

In this example, r is true when c1 is true and c3 is false or when c1 is  
true and c2 and c3 are true.

This example is extremely simplified in the hopes of conveying the  
concept.  
The actual criteria tables include 5 or 6 conditions, some boolean, some  
integer.

The reason that I would like to version the contents of this table as a  
set  
(all move to the next revision when one changes) is that I plan to store  
the  
revision of the criteria used along with the thing being evaluated.  
This  
should allow me to determine why an evaluated item failed or passed the  
criteria even in the future when the criteria have changed (possibly  
changing the evaluation result) by simply requesting the criteria for  
the  
revision that was originally used to evaluate the item in question.

I chose to put the criteria into tables instead of directly into models  
because I want to allow the system administrators to update the criteria  
in  
the future through the application.

Any ideas on other approaches?

---

<div class="post-metadata">

**Author:** ![Eden\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/6de8d8/32.png) [@Eden\_B](https://www.ruby-forum.com/u/Eden_B)\
**Post date:** [May 3, 2006, 7:07pm UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427/2 "2006-05-03T19:07:29Z")

</div>

Reposting to see if anyone in the PST time zone has any suggestions.

Thanks,

Eden

---

<div class="post-metadata">

**Author:** ![Eden\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/6de8d8/32.png) [@Eden\_B](https://www.ruby-forum.com/u/Eden_B)\
**Post date:** [May 5, 2006, 10:55pm UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427/3 "2006-05-05T22:55:13Z")

</div>

Hello? Bumping this one more time just in case someone has some free  
time  
to think this through on a Friday.

Just to summarize, I am looking for a way to version all rows in a table  
as  
a set. Any changes to any row would up rev all rows. Accessing a row  
should happen in the context of the set version, not the row version.

My current inclination is to keep the schema below (since I can’t think  
of  
another one) and modify acts\_as\_versioned so that it is really  
acts\_as\_versioned\_set.

Any other suggestions?

Thank you,

Eden

---

<div class="post-metadata">

**Author:** ![Eden\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/6de8d8/32.png) [@Eden\_B](https://www.ruby-forum.com/u/Eden_B)\
**Post date:** [May 5, 2006, 11:47pm UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427/4 "2006-05-05T23:47:39Z")

</div>

Let me see if I understand correctly. Every time any field in any row  
is changed, you need to store a copy of the whole table so that you can  
reference it later?

---

<div class="post-metadata">

**Author:** ![Eden\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/6de8d8/32.png) [@Eden\_B](https://www.ruby-forum.com/u/Eden_B)\
**Post date:** [May 6, 2006, 12:06am UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427/5 "2006-05-06T00:06:06Z")

</div>

On May 5, 2006, at 1:52 PM, Eden B. wrote:

> really acts\_as\_versioned\_set.  
> (Assuming you need locking on the set, not full versioning.)

You’re working with rulesets which aggregate rules, so lock the  
ruleset itself. Don’t CRUD rules directly; operate on them via their  
ruleset.

# Doesn’t have a version column (and likely no separate pk if AR

didn’t need it.)  
class Rule \< AR::Base; end

# Has a version column.

class Ruleset \< AR::Base  
has\_many :rules

```
 # Saving the ruleset bumps its version, so so save its rules in

```

the same transaction.  
after\_save :save\_changed\_rules  
end

ruleset.rules \<\< Rule.new(foo, bar)  
ruleset.save!

Check out Eric Evan’s _Domain Driven Design_ for an excellent  
discussion of locking on domain boundaries.

Best,  
jeremy

---

<div class="post-metadata">

**Author:** ![Eden\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/6de8d8/32.png) [@Eden\_B](https://www.ruby-forum.com/u/Eden_B)\
**Post date:** [May 6, 2006, 2:11am UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427/6 "2006-05-06T02:11:18Z")

</div>

Charlie,

Thank you for responding. Yes, I want at least a diff of the whole  
table  
each time anything changes. The table is essentially a complicated  
lookup  
table (lots of variables in, one answer out), so the number of total  
rows is  
limited (about 10 right now). The table is functioning as a set of  
criteria. I pass in a bunch of true/false values (plus one or two ints)  
and  
get a pass or fail type result out of the table. Each combination of  
inputs  
will only match one row in the table.

Does that help? I can post the actual contents of one of these criteria  
tables (there are several) if you think it will clarify things.

Thanks,

Eden

---

<div class="post-metadata">

**Author:** ![Eden\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/6de8d8/32.png) [@Eden\_B](https://www.ruby-forum.com/u/Eden_B)\
**Post date:** [May 6, 2006, 2:14am UTC](https://www.ruby-forum.com/t/versioning-the-contents-of-a-table-as-a-set/59427/7 "2006-05-06T02:14:25Z")

</div>

I think you hit the nail on the head Jeremy! I think all I would need  
to do  
is store the ruleset id in the item that is evaluated. Then I can  
always  
refer back to the ruleset that was used for the evaluation even if the  
rules  
are modified (each modification is actually a new ruleset).

I will check out the reference.

Thanks again,

Eden
