I’m pondering a way of representing a scenario without too much
fiddling with the database. I’m 90% happy with it, but have one
problem (where I probably just don’t know the right AR approach to
use).
I have a “people” table, from which records are displayed depending on
whether they are new leads, exisiting customers, or just contacts
(maybe reps at stores). I’m keeping them in one DB table, but I don’t
want to use STI, as a single person might be more than one “type”.
Here’s the reasoning:
A Person can be flagged as “new lead”.
A Person can have Orders (which makes them a customer).
A NewLead can have Orders - for instance trial packs that their sales
person has sent them - which makes them a customer as well as a lead.
A Person record can exist, and be neither a Customer or NewLead (I’m
calling these guys “contacts” for now, but they might as easily be
Foos or Bars…)
I want to be able to access the records using named_scopes, as, of
course, I want to be able to chain other scopes - so named_scopes are
essential (so I can get all the NewLeads for a given sales person, or
all the Contacts with a given surname, etc)
So I’ve got this structure:
class Person < ActiveRecord::Base
…Person stuff
end
class NewLead < Person
default_scope :conditions => “people.new_lead = 1” # … simple
condition to return only new leads
end
class Customer < Person
default_scope :group => “people.id”, :joins => :orders # …
returns me unique instances (thanks to the :group) of just those
people who have any order records
end
class Contact < Person
#… my problem… what does my default scope need to be to return
me people without orders, and with the “new_lead” flag set to zero?
end
The logic for NewLead and Customer is working perfectly - if I have a
Person with id=123 who has no orders, but new_lead set to “1”, calling
“NewLead.find(123)” gives me a valid NewLead record, but
“Customer.find(123)” gives me a “record not found error” - just what I
want to happen. Then if that person has an order placed for them, both
of the finds returns a valid record.
But how to return records with no Orders… ? I’m thinking that I may
need something along the lines of:
default_scope :conditions => “people.id not in (select distinct
people.id from people joins orders on orders.person_id = people.id)
and people.new_lead = 0”
But that seems ugly.
Any suggestions for neater ways?