Forum: Ruby on Rails Controller/View Organization (Newbie Question)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
5184e8d86d9d5534b1f9e50d972548ea?d=identicon&s=25 Justin Streufert (Guest)
on 2006-03-17 18:33
(Received via mailing list)
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
59de94a56fd2c198f33d9515d1c05961?d=identicon&s=25 Tom Mornini (Guest)
on 2006-03-17 19:32
(Received via mailing list)
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
5184e8d86d9d5534b1f9e50d972548ea?d=identicon&s=25 Justin Streufert (Guest)
on 2006-03-18 04:45
(Received via mailing list)
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
This topic is locked and can not be replied to.