0

There are three questions here, all of them set in bold.

I have a personnel database where historical data is also stored. Each table has two columns start and stop which indicate the period during which this fact is valid.

When any field of a record changes, a new record is created with start=today, and stop=nil, and the old record is given a stop=today-1 (or whatever the effective date of the change is instead of today).

When a record is to be deleted, instead of deleting, we simply set stop=today.

This way, it is easy to

  • give a history of any employee
  • give a snapshot of what things looked like on a particular date

Firstly this pattern seems common enough that probably I should not need to re-invent the wheel. Yet in my search all I found were some gems called auditable or papertrail. From a first glance, they did not seem to do what I want, but perhaps I am mistaken. Do you know of a gem that does something similar?

If I don't find a solution, what is enough for my purposes is to have a few methods which works for all my models, like

def when(date)
    self.where("start <= ? and ? <= stop", ondate, ondate)
end

I thought about inheriting

class MyRecord < ActiveRecord::Base
    def when ...
    end
end

and having all my models inherit from MyRecord, but this broke everything. Why?

I could just add my methods to ActiveRecord::Base, but that seems wrong. What is the proper way to add a method to all models?

Answer

Parts 2 and 3 of this question have been answered before here. Since that contains Josh's answer (which I +1ed), as well as why inheriting from MyRecord doesn't work, I did not accept Josh's answer.

I still have not located a gem which maintains a good history, but two out of three ain't bad...

Community
  • 1
  • 1
Roobie Nuby
  • 1,379
  • 12
  • 19
  • 1
    `having all my models inherit from MyRecord, but this broke everything.` what did broke? – Raj May 13 '14 at 17:50
  • The other way to do it is to put your common code in a module and include that in all your models that need it, but yeah, your inheritance solution should have worked. – Dave Schweisguth May 13 '14 at 17:59
  • @emaillenin "What did broke?" Now I don't remember so I tried to reproduce. First question: Where does this file my_record.rb go? In models it tries to find a table with that name. In helpers it still has the same complaint. – Roobie Nuby May 13 '14 at 18:10

1 Answers1

1

This sounds to me like an excellent opportunity to use an ActiveSupport::Concern. You could write something like:

History.rb

require 'active_support/concern'

module History
  extend ActiveSupport::Concern
  included do
    def self.when(date)
      self.where("start <= ? and ? <= stop", ondate, ondate)
    end
  end
end

Your model

class SomeClass < ActiveRecord::Base
  include History
end

You could then call SomeClass.when(some_date_string) on any models that you need to include history on.

Josh
  • 5,631
  • 1
  • 28
  • 54