# Model question

**URL:** <https://www.ruby-forum.com/t/model-question/186925>\
**Category:** Rails\
**Created:** [April 14, 2010, 1:19pm UTC](https://www.ruby-forum.com/t/model-question/186925 "2010-04-14T13:19:14Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mariachi77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/d2c977/32.png) [@mariachi77](https://www.ruby-forum.com/u/mariachi77)\
**Post date:** [April 14, 2010, 1:19pm UTC](https://www.ruby-forum.com/t/model-question/186925/1 "2010-04-14T13:19:14Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![mariachi77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/d2c977/32.png) [@mariachi77](https://www.ruby-forum.com/u/mariachi77)\
**Post date:** [April 14, 2010, 1:39pm UTC](https://www.ruby-forum.com/t/model-question/186925/2 "2010-04-14T13:39:43Z")

</div>

On 14 April 2010 12:32, Andy J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Andy  
> Nice idea… that would do well, and clean it up a bit - I just tried  
> my approach (after fixing typos…) and it works, but just smells…  
> 🙂

Thanks for that.

---

<div class="post-metadata">

**Author:** ![mariachi77](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/d2c977/32.png) [@mariachi77](https://www.ruby-forum.com/u/mariachi77)\
**Post date:** [April 14, 2010, 1:33pm UTC](https://www.ruby-forum.com/t/model-question/186925/3 "2010-04-14T13:33:52Z")

</div>

> But how to return records with no Orders… ? I’m thinking that I may  
> need something along the lines of:  
> But that seems ugly.
> 
> Any suggestions for neater ways?

How about using counter caches - something like:

class Order \< ActiveRecord::Base  
belongs\_to :customer, :counter\_cache =\> true  
end

class Customer \< Person  
has\_many :orders  
default\_scope :conditions =\> { :orders\_count \> 0}  
end

> **[rails.info](http://guides.rails.info/association_basics.html#belongs-to-association-reference)**
>
> Ruby on Rails,Rails Tutorial,Ruby Basics,Rails 4,Bar Rails,Rail

(section 4.1.2.4)

Cheers,

Andy
