views:

44

answers:

3

Hi,

I have four models: Customer, QueueRed, QueueBlue, QueueGreen.

The Queue models have a one to many relationship with customers

A customer must always be in a queue

A customer can only be in one queue at a time

A customer can change queues

We must be able to find out the customers current position in their respective queue

In an object model the queues would just have an array property containing customers, but ActiveRecord doesn't have arrays.

In a DB I would probably create some extra tables just to handle the order of the stories in the queue.

My question is what it the best way to model the relationship in ActiveRecord? Obviously there are many ways this could be done, but what is the best or the most in line with how ActiveRecord should be used?

Cheers,

Chris

+2  A: 

You should probably be looking at the acts_as_list plugin.

Steve Weet
+2  A: 

I'd suggest to create only two models: Customer and Queue.

Queue table should consists of: customer_id, queue_type_id, position. You can create also QueueType model, but it is not necesary.

Customer model:

has_one :queue

Queue model:

belongs_to :customer

validates_uniqueness_of :customer_id
validates_uniqueness_of :position, :scope => :queue_type_id

named_scope :red, :conditions => {:queue_type_id => 0}
named_scope :green, :conditions => {:queue_type_id => 1}
named_scope :blue, :conditions => {:queue_type_id => 2}

I added named scopes to handle colours of queues.

A customer can only be in one queue at a time

First validation in queue model should forbid customer to be in more than one queue.

A customer can change queues

@customer = Customer.first
@customer.queue.queue_type_id = 1
@customer.save

Here you shoud be carfull with position in queue, because it has to be unique in scope of queue_type_id.

We must be able to find out the customers current position in their respective queue

customer.queue.position

In an object model the queues would just have an array property containing customers, but ActiveRecord doesn't have arrays.

@queue = Queue.red

It returns array of customers. I don't know what you meant by "ActiveRecord doesn't have arrays".

A customer must always be in a queue

Hm, just:

@customer = Customer.new
@customer.build_queue

? Or you can add some before_save or maybe better, simple validation:

validate :ensure_customer_is_in_queue

def ensure_customer_is_in_queue
  errors.add_to_base "Customer should be in a queue!" unless self.queue
end
klew
A: 

This is a commment/addition to the accepted answer above.

acts_as_list is not designed for anything beyond a prototype, and out of the box it does not handle concurrency or data integrity at all. At the very least, you must set your isolation level to serializable! Here's a short screen cast with more information, and some workarounds.

Xavier Shay