Application Design

I have a question about how to implement a design in Rails. I will try
to make this as easy to follow as possible. First, let’s say that I
have an ‘Orders’ table that has different statuses. The 3 statuses that
I want to track are ‘Submitted’, ‘Approved’, and ‘Purchased’.
I also have 3 users of this application.

  • User A can submit an order
  • User B should only see orders with ‘Submitted’ status and can
    ‘Approve’ orders
  • User C should only see ‘Submitted and Approved’ orders and can
    ‘Purchase’ the order

I realize this is more of a workflow question, but I’m trying to figure
out the best way to structure this.

Here is one thought…

Statuses Table

ID
Name

Orders Table

ID
Name

Orders_Statuses

order_id
status_id

Then, I can do a join in the model to only return the correct rows. Is
this the correct way to do this? Also, what type of logic should I be
doing in the controller (i.e. Making sure that the Order is approved and
submitted before Purchasing can order it)?
Please see the following link for the BlueCross BlueShield of Tennessee
E-mail
disclaimer: http://www.bcbst.com/email_disclaimer.shtm

Campano, David wrote:

I have a question about how to implement a design in Rails. I will try
to make this as easy to follow as possible. First, let’s say that I
have an ‘Orders’ table that has different statuses. The 3 statuses that
I want to track are ‘Submitted’, ‘Approved’, and ‘Purchased’.
I also have 3 users of this application.

  • User A can submit an order
  • User B should only see orders with ‘Submitted’ status and can
    ‘Approve’ orders
  • User C should only see ‘Submitted and Approved’ orders and can
    ‘Purchase’ the order

I realize this is more of a workflow question, but I’m trying to figure
out the best way to structure this.

Your join table would work but to me it makes more sense to have a
single status associated with an order. Then your Orders table would
just include a status_id column. You statuses would change:

  1. New (or just a nil status_id)
  2. Submitted
  3. Approved
  4. Purchased

Jake

Is it correct to assume that “submitted”, “approved”, and “purchased”
are mutually exclusive “states”? If so, then why not have one table
with a field for this state? You can then structure your queries so
that they select the permitted state(s) for a particular user.

Otherwise, you’ll be copying orders from one table to the next whenver
a state change occurs and you’ll also be doing joins over several
tables for some queries.

My $0.02,

dean

On 4/24/06, Campano, David [email protected] wrote:

  • User B should only see orders with ‘Submitted’ status and can ‘Approve’

order_id


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails


Dean W.
http://www.aspectprogramming.com

http://www.contract4j.org

Since ‘status’ is probably a property of the order, I probably would not
create a separate class for it unless it was truly necessary.

it’s not too hard to do

Order.find_all_by_status(‘Complete’)

Then you only need one table

Orders
– id
– name
– status

As for the rest, I’d take a look at the user/login engine combo as it
has some nice role based access control (there are others).

You can create a view/controller method for each of the 3 cases you
describe.
Most of the role bases access control systems will allow you to restrict
who can access which controller/action pair.

On Monday, April 24, 2006, at 10:16 AM, Campano, David wrote:

  • User C should only see ‘Submitted and Approved’ orders and can
    Name

Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

_Kevin

On Monday 24 April 2006 15:29, Kevin O. wrote:

Since ‘status’ is probably a property of the order, I probably would not Â
create a separate class for it unless it was truly necessary.

Just to clarify what I say below, status might be a property of the
order, but
the name of that status isn’t, hence it should go in a separate table.

– status
I would avoid this personally - it opens you up to inserting invalid
statuses
in the orders table, duplicates the status name which wastes space, and
means
if you ever want to change the description of a status, you have to
update
every order with that status. Personally I don’t think this strategy is
ever
worth the risk.

Ashley

Kevin O. wrote:

I would suggest that over-complicating the problem carries it’s own
risks.

I’d agree with that. I’d leave the db with an integer status code, and
use composed_of to (in the words of Chad F.'s Rails Receipes) make
dumb data smart.

If your db has a ‘statuscode’ column, and you’d like a ‘status’
attribute which is an object, you could do:

class Order < ActiveRecord::Base
composed_of :status,
:class_name => ‘Status’,
:mapping => [%w(statuscode status)]
end

Alan

I would suggest that over-complicating the problem carries it’s own
risks.
While strictly speaking, you are correct, it is also not very hard to
deal with.

For example, what if someone accidentally deletes a record from your
‘statuses’ table? Best case, it breaks things when the database can’t
find the status id, and worst case, it deletes all the records with that
status (if you have your models set up wrong).

If you don’t let the user type in the status directly, you can just use
global array with the values in it. I presume that you won’t be
creating a lot of new types of statuses as you go along. In any case,
if you want to do it that way, then follow some of the other poster’s
suggestions.

use
Order
belongs_to :status
Status
has_many :orders, :dependent=>:nullify

and make sure there is a status_id field in order.

On Monday, April 24, 2006, at 5:24 PM, Ashley M. wrote:

it’s not too hard to do
I would avoid this personally - it opens you up to inserting invalid
Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

_Kevin