Justin Streufert
2006-Mar-17 17:30 UTC
[Rails] Controller/View Organization (Newbie Question)
Good afternoon all... First, let me apologize for asking a potentially dumb question. I''m new to both Ruby and Rails, but I do have a long background in OO programming and web development. My question is about how to structure controllers for the various models which I will need in my application. My data will look something like this: Dog - (has_many) TrainingSessions - (has_many) Tests - (has_many) Behaviors So, obviously, the "Dog" object is the central object on which users will be working when they visit the application. I have a Controller for the Dog object whose "show" view will display an overview of the data and link to other views for adding/editing/deleting data relating to the Dog. My question is about the accepted or "best practice" way to lay out these auxiliary views. I''ve thought of a few ways to do this: 1. Make a controller for each of the auxiliary objects (TrainingSessionsController, TestsController, etc), each with a view to show information only relating to the current Dog in question. So for example, the overview URL "/dogs/show/1" might link to a detail page at "/training_sessions/list?dog_id=1" .. This seems ugly to me, as I will need to keep passing around parameters in the URL wherever I go to make sure we''re still working on the right dog. For example, I''ll need to remember to pass ?dog_id=... to "/training_sessions/new" so that dog_id in the training_sessions table can be set correctly. A lot of extra code and work. 2. Do the same as #1 (one Controller per table) but use a session variable to pass around the dog_id. This would reduce repetition but strikes me as less than robust. (?) 3. Do the same as #1, but use routing to make the URLs for the auxiliary table methods look something like: "/dog/1/ training_sessions/list". As I understand it, the linking helpers would then maintain the dog ID at the beginning of the URL unless I specifically overrode it. (Though I haven''t actually TRIED this yet, so I could be wrong) 4. Use only ONE controller (for Dog) and implement all auxiliary data operations (CRUD) as sets of views/methods on DogsController. Then, to get around the problem of having to have two IDs at once -- one for the dog and one into the auxiliary table -- maybe set up routing to allow /dogs/3/show_training_session/4 or /dogs/ show_training_session/3/4 or something along those lines. This seems "clean" but I can also see this class getting way too big and unwieldy with all of these methods. The biggest possibility of all is that I am missing some glorious way Rails has for handling this sort of situation, and someone can set me straight with a link to a web page or API doc ;) Either way, I would be extremely grateful for any input you might have. Thank you! Justin Streufert monitron@gmail.com
On Mar 17, 2006, at 9:30 AM, Justin Streufert wrote:> My question is about the accepted or "best practice" way to lay out > these auxiliary views. I''ve thought of a few ways to do this:snip...> 3. Do the same as #1, but use routing to make the URLs for the > auxiliary table methods look something like: "/dog/1/ > training_sessions/list". As I understand it, the linking helpers > would then maintain the dog ID at the beginning of the URL unless I > specifically overrode it. (Though I haven''t actually TRIED this > yet, so I could be wrong)snip...> 4. Use only ONE controller (for Dog) and implement all auxiliary > data operations (CRUD) as sets of views/methods on DogsController. > Then, to get around the problem of having to have two IDs at once > -- one for the dog and one into the auxiliary table -- maybe set up > routing to allow /dogs/3/show_training_session/4 or /dogs/ > show_training_session/3/4 or something along those lines. This > seems "clean" but I can also see this class getting way too big and > unwieldy with all of these methods.I''d use a combination of 3 and 4. Set up routing with an additional: map.connect '':controller/:action/:id/:id2'' And just split the controllers where logical, but do NOT use one per table as the scaffolding suggests (unless you decide that makes sense). I''m not bagging on the scaffolding, but it''s generated by a script, not by a decision maker. For instance, and potentially contrived: I could see a: dogs_controller.rb dog.rb training_controller.rb training_sessions.rb diagnostics_controller.rb test.rb behavior.rb -- -- Tom Mornini
Justin Streufert
2006-Mar-18 03:44 UTC
[Rails] Controller/View Organization (Newbie Question)
Thanks very much for your answer, Tom! I ended up doing exactly what you said, except that I used these routes: map.connect '':controller/:id/:action/:sub_id'', :requirements => { :id => /\d+/ } map.connect '':controller/:id/:action'', :requirements => { :id => / \d+/ } map.connect '':controller/:action'' ...which, due to the hierarchical nature of the URL generator (as I just learned in Agile Web Development with Rails ;)) seems to result in more natural linking. Thanks again!! I''m now well on my way. Justin On Mar 17, 2006, at 1:29 PM, Tom Mornini wrote:> On Mar 17, 2006, at 9:30 AM, Justin Streufert wrote: > >> My question is about the accepted or "best practice" way to lay >> out these auxiliary views. I''ve thought of a few ways to do this: > > snip... > >> 3. Do the same as #1, but use routing to make the URLs for the >> auxiliary table methods look something like: "/dog/1/ >> training_sessions/list". As I understand it, the linking helpers >> would then maintain the dog ID at the beginning of the URL unless >> I specifically overrode it. (Though I haven''t actually TRIED this >> yet, so I could be wrong) > > snip... > >> 4. Use only ONE controller (for Dog) and implement all auxiliary >> data operations (CRUD) as sets of views/methods on DogsController. >> Then, to get around the problem of having to have two IDs at once >> -- one for the dog and one into the auxiliary table -- maybe set >> up routing to allow /dogs/3/show_training_session/4 or /dogs/ >> show_training_session/3/4 or something along those lines. This >> seems "clean" but I can also see this class getting way too big >> and unwieldy with all of these methods. > > I''d use a combination of 3 and 4. > > Set up routing with an additional: > > map.connect '':controller/:action/:id/:id2'' > > And just split the controllers where logical, but do NOT use one > per table as the > scaffolding suggests (unless you decide that makes sense). I''m not > bagging on the > scaffolding, but it''s generated by a script, not by a decision maker. > > For instance, and potentially contrived: > > I could see a: > > dogs_controller.rb > dog.rb > > training_controller.rb > training_sessions.rb > > diagnostics_controller.rb > test.rb > behavior.rb > > -- > -- Tom Mornini > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails