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 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060424/c8d7683d/attachment.html
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 -- Posted via http://www.ruby-forum.com/.
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 <David_Campano@bcbst.com> 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. > > 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 > > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > >-- Dean Wampler http://www.aspectprogramming.com http://www.newaspects.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:>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 > > >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/rails >_Kevin -- Posted with http://DevLists.com. Sign up and save your mailbox.
On Monday 24 April 2006 15:29, Kevin Olbrich 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.> > it''s not too hard to do > > Order.find_all_by_status(''Complete'') > > Then you only need one table > > Orders > -- id > -- name > -- statusI 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
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 Moran wrote:>On Monday 24 April 2006 15:29, Kevin Olbrich 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. > >> >> it''s not too hard to do >> >> Order.find_all_by_status(''Complete'') >> >> Then you only need one table >> >> Orders >> -- id >> -- name >> -- 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 >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/rails_Kevin -- Posted with http://DevLists.com. Sign up and save your mailbox.
Thanks everyone for the great responses! I really appreciate the great feedback. One more question. Let''s say that I only want the user that submitted the order to be able to delete it. Right now I am tracking that user''s id in session[:user_id] and there is a user_id column in the orders table. Is the best place to check if this user should be able to delete in the controller or model? Right now I have created a ''is_order_owner?'' method in the controller that I use in an If statement before executing the delete. Is this the appropriate place to put the code, or should I have it in the model? -----Original Message----- From: rails-bounces@lists.rubyonrails.org [mailto:rails-bounces@lists.rubyonrails.org]On Behalf Of Kevin Olbrich Sent: Monday, April 24, 2006 12:41 PM To: rails@lists.rubyonrails.org Subject: Re: [Rails] Application Design 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 Moran wrote:>On Monday 24 April 2006 15:29, Kevin Olbrich 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. > >> >> it''s not too hard to do >> >> Order.find_all_by_status(''Complete'') >> >> Then you only need one table >> >> Orders >> -- id >> -- name >> -- 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 >_______________________________________________ >Rails mailing list >Rails@lists.rubyonrails.org >http://lists.rubyonrails.org/mailman/listinfo/rails_Kevin -- Posted with http://DevLists.com. Sign up and save your mailbox. _______________________________________________ Rails mailing list Rails@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails Please see the following link for the BlueCross BlueShield of Tennessee E-mail disclaimer: http://www.bcbst.com/email_disclaimer.shtm
On Apr 24, 2006, at 9:52 AM, Campano, David wrote:> Thanks everyone for the great responses! I really appreciate the > great feedback. > > One more question. Let''s say that I only want the user that > submitted the order to be able to delete it. Right now I am > tracking that user''s id in session[:user_id] and there is a user_id > column in the orders table. > Is the best place to check if this user should be able to delete in > the controller or model? Right now I have created a > ''is_order_owner?'' method in the controller that I use in an If > statement before executing the delete. Is this the appropriate > place to put the code, or should I have it in the model?I''m assuming you''re using session[:user_id] to find a user on logged in pages. I''d put a method in Order like this: def destroy_by_user(user) if user.id == order.user.id destroy true else false end end And in the controller I''d say; if order.destroy_by_user(@logged_in_user) # success else # failure end -- -- Tom Mornini
Kevin Olbrich 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 Fowler''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 -- Posted via http://www.ruby-forum.com/.