Reputation: 11162
I'm working on a rails app where the associations between data change with time. I've created a model for the associations:
create_table :accounts_numbers do |t|
t.integer :number_id
t.integer :account_id
t.date :start_date
t.date :end_date
And, so far, I have a simple model
class Account < ActiveRecord::Base
has_and_belongs_to_many :numbers, :through => accounts_numbers
end
But instead of
@account.numbers
I need something like
@account.numbers_at(Date.new(2010,2,3))
I thought I could use :conditions
, but I wouldn't haven't seen a way to tell has_and_belongs_to_many
to create a parameterized field. I've also looked into named_scope
, but that only seems to return accounts, not numbers.
More importantly, this pattern is going to cover many relationships in my code, so would there be a way to coin a time_dependent_has_and_belongs_to_many
for use all over?
Upvotes: 2
Views: 134
Reputation: 11162
After much more searching, I finally found out what to do; In the /lib
dir of my project, I created a module, TimeDependent
:
module TimeDependent
def at(date)
find(:all, :conditions=>["start_date <= ? AND ? < end_date"], date, date)
end
end
So, my model becomes
require "TimeDependent"
class Account < ActiveRecord::Base
has_many :accounts_numbers
has_many :numbers, :through => :accounts_numbers, :extend => TimeDependent
end
Which allows me to do exactly what I want:
@numbers = @account.numbers.at(Date.new(2010,2,3));
Upvotes: 1
Reputation: 90
Couldn't this be done by writing a function for Object?
class Object
def numbers_at(time)
start = time.to_date
end = time.advance(:days => 1).to_date
AccountNumber.join(:accounts, :numbers).where("time BETWEEN(?, ?)", start, end)
end
end
Upvotes: 0