Hatred towards Nested Polymorphic Paths

39 views
Skip to first unread message

Josh Peek

unread,
Jul 7, 2007, 1:25:37 AM7/7/07
to Ruby on Rails: Core
I have a real grudge against the new nested polymorphic path magic
stuff. I feel it encourages and gives people an excuse to write overly
compelled routes. Resources should NOT be nested more than one level
deep.

"/companies/1/people/1" == BAD
"/people/1" == GOOD

I have no problem with nested collections.

"/companies/1/people"

You shouldn't need to be scoping person #1 if its the unique id.

I've seen alot of defect and enhancement tickets going by Trac showing
its immaturity and lack of real need. None of this stuff has been
merge with the stable, so its not to late to change things. It should
really be pulled from Edge and into a plugin,
"nested_polymorphic_paths".

Its not in the spirit of Rails to be providing tools to help you
practice bad habits.

Evan Weaver

unread,
Jul 7, 2007, 2:14:36 AM7/7/07
to rubyonra...@googlegroups.com
I tend to agree with this. I don't really understand the need to
"canonically" identify a resource based on its context.

Other thoughts?

Evan

> --
> Evan Weaver
> Cloudburst, LLC
>


--
Evan Weaver
Cloudburst, LLC

Daniel N

unread,
Jul 7, 2007, 2:40:39 AM7/7/07
to rubyonra...@googlegroups.com


I wondered about the usefulness of this one too when it came out.  But I in fact have a situation where I feel it is warranted to have the nested routes like this.

Each user has a collection of books.
Each book has a collection of clips.

Clips can be shared between books.
A Clip has a default view depending on which book your in when your looking at it.  ( Data kept in the join model of the :through association )

This makes it important to have both pieces of information.  This is I believe the same for any has_many :through association where you have additional information in the join model.  Without both pieces of information you can't identify the correct join model to use and therefore the extra piece of information you need.

Please let me know if there is another way to do what I'm suggesting.

Cheers
Daniel


Joshua Sierles

unread,
Jul 7, 2007, 10:23:01 AM7/7/07
to rubyonra...@googlegroups.com

On Jul 7, 2007, at 8:14 AM, Evan Weaver wrote:

>
> I tend to agree with this. I don't really understand the need to
> "canonically" identify a resource based on its context.
>
> Other thoughts?
>
> Evan

The simple reason would be that you want your URLs to look that way.

Joshua

Josh Peek

unread,
Jul 7, 2007, 10:54:21 AM7/7/07
to Ruby on Rails: Core
On Jul 7, 1:40 am, "Daniel N" <has....@gmail.com> wrote:
> This makes it important to have both pieces of information. This is I
> believe the same for any has_many :through association where you have
> additional information in the join model. Without both pieces of
> information you can't identify the correct join model to use and therefore
> the extra piece of information you need.

Whats the join model in this case? Can you pastie the example? (http://
pastie.caboo.se/)

Because each clip (and every other model you mentioned) has its own
unique id, you can always use that to find it.

DHH

unread,
Jul 7, 2007, 11:08:42 AM7/7/07
to Ruby on Rails: Core
> "/companies/1/people/1" == BAD
> "/people/1" == GOOD
>
> You shouldn't need to be scoping person #1 if its the unique id.
>
> Its not in the spirit of Rails to be providing tools to help you
> practice bad habits.

I think this is going too far. I too prefer to limit the scope to one
level, but there are legitimate reasons to have deeper nesting. /
albums/45/tracks/1 (where the track number is scoped on the album). Or
closer to home, /forums/5/threads/1 and /forums/15/threads/1.

I think it's perfectly fine to encourage people to not nest when they
don't really care one way or another. But to outright "forbid" it is
pushing it.

What are your technical grudges against this? And what would be better
if we didn't support it?

DHH

unread,
Jul 7, 2007, 11:12:36 AM7/7/07
to Ruby on Rails: Core
> > I tend to agree with this. I don't really understand the need to
> > "canonically" identify a resource based on its context.
>
> > Other thoughts?
>
> The simple reason would be that you want your URLs to look that way.

I think this is also a reasonable argument. Again, I'm actually in the
camp of it "not being worth it" from an effort/gain perspective to do
fully nested URLs, but I don't want to push that dictate on someone
else. The URL is half-ways part of the UI design and I'm very
hesistant to push UI conventions on anyone.

Rails applications should be able to look completely incognito.

Mislav Marohnić

unread,
Jul 7, 2007, 11:15:29 AM7/7/07
to rubyonra...@googlegroups.com
On 7/7/07, DHH <david.he...@gmail.com> wrote:

> You shouldn't need to be scoping person #1 if its the unique id.

I think this is going too far. I too prefer to limit the scope to one
level, but there are legitimate reasons to have deeper nesting. /
albums/45/tracks/1 (where the track number is scoped on the album).

I think Josh's grudge is against:

  /tracks/219 == /albums/45/tracks/219

... where the track id is the unique ID of the track. This is perfectly fine with me, on the other hand:

  albums/45/tracks/1

... but then we're talking about composite primary keys, which aren't popular amongst Rails devs.

Josh Peek

unread,
Jul 7, 2007, 11:50:36 AM7/7/07
to Ruby on Rails: Core

On Jul 7, 10:08 am, DHH <david.heineme...@gmail.com> wrote:
> I think it's perfectly fine to encourage people to not nest when they
> don't really care one way or another. But to outright "forbid" it is
> pushing it.

I wasn't clear about banning what..

I wanted to remove the whole polymorphic nesting with an array:
polymorphic_path([@artist, @album, @track]). If you want to do
something like that, use the old school named route for it:
artist_album_track_path(@artist, @album, @track). I've seen a ton of
tickets of people trying to extend polymorphic_path([...]) to do
everything for them when a proper work around with named routes will
do.

Geoff B

unread,
Jul 7, 2007, 11:59:57 AM7/7/07
to Ruby on Rails: Core
So, are you saying that, instead of doing this:

link_to @track.name, [@album, @track]

...we should be required to do this:

link_to @track.name, album_track_path(@album, @track)

?

Josh Peek

unread,
Jul 7, 2007, 12:04:21 PM7/7/07
to Ruby on Rails: Core
On Jul 7, 10:59 am, Geoff B <gbues...@gmail.com> wrote:
> So, are you saying that, instead of doing this:
>
> link_to @track.name, [@album, @track]
>
> ...we should be required to do this:
>
> link_to @track.name, album_track_path(@album, @track)

I'm saying you should be doing ...

link_to @track.name, @track

Like I said, [@album, @track] is giving you an excuse to use complex
routing patterns.

Geoff B

unread,
Jul 7, 2007, 12:12:48 PM7/7/07
to Ruby on Rails: Core
I think a case can be made for using an [@album, @track] nested route
-- say a user browsed to album 45, and then clicked track 219 -- if
your UI requires a "back to album 45" navigational link on the track
page, you couldn't infer the referring album id from the resource id
alone if there's a many-to-many relationship between albums and tracks
-- instead, you'd need to grab the album id from the URI.

Josh Peek

unread,
Jul 7, 2007, 12:18:42 PM7/7/07
to Ruby on Rails: Core
On Jul 7, 11:12 am, Geoff B <gbues...@gmail.com> wrote:
> I think a case can be made for using an [@album, @track] nested route
> -- say a user browsed to album 45, and then clicked track 219 -- if
> your UI requires a "back to album 45" navigational link on the track
> page, you couldn't infer the referring album id from the resource id
> alone if there's a many-to-many relationship between albums and tracks
> -- instead, you'd need to grab the album id from the URI

If your referring to a HABTM relationship, look into creating a real
join model between them using has many though. That why you have a
real resource you can point your url to.

Josh Peek

unread,
Jul 7, 2007, 12:21:08 PM7/7/07
to Ruby on Rails: Core
On Jul 7, 11:12 am, Geoff B <gbues...@gmail.com> wrote:

Since you are so passionate about nested polymorphic resource, it
seems like a perfect fit for you to make and maintain a plugin for
this.

Gabe da Silveira

unread,
Jul 7, 2007, 12:24:46 PM7/7/07
to rubyonra...@googlegroups.com
I gotta agree here. Presuming that people should always use
root-level routes is going too far. The URL carries a lot of
information, and why shouldn't the developer have access to it? Plus
I don't really see how this polymorphic routing magic has much effect
on people's design decisions. I don't think anyone is going to
arbitrarily choose nested routing just because they don't have to use
a named helper. There are so many other considerations at play, and
jamming an array into link_to is not exactly magically delicious.

It sounds like the real issue is that there are too many patches and
too many bugs to manage. Well if it can't be implemented cleanly then
maybe it should be pulled. But the whole "encouraging bad practices"
seems spurious.


--
Gabe da Silveira
http://darwinweb.net

Josh Peek

unread,
Jul 7, 2007, 12:28:23 PM7/7/07
to Ruby on Rails: Core
On Jul 7, 11:24 am, "Gabe da Silveira" <gabrie...@gmail.com> wrote:
> It sounds like the real issue is that there are too many patches and
> too many bugs to manage. Well if it can't be implemented cleanly then
> maybe it should be pulled.

Another point I was trying to make. If it was pulling into a plugin
and matured a little, it could then be considered for reentry.

Pratik

unread,
Jul 7, 2007, 12:41:55 PM7/7/07
to rubyonra...@googlegroups.com
Can you please point out to tickets related to the issue ? They'd
surely provide a better insight to your point.

Thanks,
Pratik

On 7/7/07, Josh Peek <josh...@gmail.com> wrote:
>


--
http://m.onkey.org

Josh Peek

unread,
Jul 7, 2007, 12:50:32 PM7/7/07
to Ruby on Rails: Core

On Jul 7, 11:41 am, Pratik <pratikn...@gmail.com> wrote:
> Can you please point out to tickets related to the issue ? They'd
> surely provide a better insight to your point.

Heres a few: [7152], #8725, #8782, #8719, #8720, #8705, #8830, #8654,
#8640

psada...@gmail.com

unread,
Jul 7, 2007, 2:17:50 PM7/7/07
to Ruby on Rails: Core
I'm working on a project now, where we have things like:

/album/1/tracks
/tracks #=> not valid
/tracks/1 #=> valid
/tracks/1/artists #=> Assume a track has many artists
/artists/1/tracks #=> reverse of above; all the tracks for an
artist.

Basically, we want `/foo/x/bar` to be valid, but not `/foo/x/bar/y`.
And we want `/bar/y` to be valid, but not `/bar`. We're finishing up a
plugin that defines those partial routes: index and create as nested
resources, and show, edit and delete as non-nested.

Daniel N

unread,
Jul 7, 2007, 2:22:59 PM7/7/07
to rubyonra...@googlegroups.com


I can't pastie it unfortunately but it.  But I believe it goes for any time you use a has_many :through relationship with additional data in the join table.  Without both sides of the join, you can't identify  join, and therefore don't have access to the extra data.

In my case it's a view setting. 

As another example,

users have mailboxes, and each mailbox can have many postcards
Mailboxes -> Postcards

Postcards are shared between users and mailboxes.  One use likes to see a particular postcards picture, whilst one likes to see it's text.  The only place to put this view information that I can see is in the join table between the postcard and mailbox.

With this situation you need both the mailbox and the clip id to determine what view state the postcard should be in.  The nested routes fit this perfectly. 






Pratik

unread,
Jul 7, 2007, 2:23:55 PM7/7/07
to rubyonra...@googlegroups.com
Those look like legitimate bugs in implementation, rather than caused
by confusion. I don't really see a point in extracting that
functionality in a plugin, with hope of making a come back to core. If
it's gets converted into a plugin, it should stay there, always.

Also, converting an edge functionality into a plugin because of
defects in implementation, defeats the whole purpose of having edge at
first place. I guess it's time to make a choice once and for all, if
it's gonna be in core rails or not.

My vote is to keep it in edge for points explained in posts above.

Thanks,
Pratik

On 7/7/07, Josh Peek <josh...@gmail.com> wrote:
>
>


--
http://m.onkey.org

Josh Peek

unread,
Jul 7, 2007, 2:37:51 PM7/7/07
to Ruby on Rails: Core

On Jul 7, 1:22 pm, "Daniel N" <has....@gmail.com> wrote:
> I can't pastie it unfortunately but it. But I believe it goes for any time
> you use a has_many :through relationship with additional data in the join
> table. Without both sides of the join, you can't identify join, and
> therefore don't have access to the extra data.

You identify the join with the id of the join model. Thats the purpose
of using has many though, exposing an actual model. If you could
pastie on example, I could show you how to model it better.

Chris Cruft

unread,
Jul 8, 2007, 4:04:24 PM7/8/07
to Ruby on Rails: Core
Josh Writes:

>"/companies/1/people/1" == BAD
>"/people/1" == GOOD
>
>I have no problem with nested collections.
>
>"/companies/1/people"
>
>You shouldn't need to be scoping person #1 if its the unique id.

But isn't that the rub? Who says the ids must be unique? True, Rails
support for composite keys makes it less-than-direct to convert the
REST resource with composite keys into an AR model with unique keys,
but from a UI point of view, some may just want to expose more
intuitive composite keys:

/month/3/week/2/day/1
/albums/6552/track/1
/cuisines/46598/popular_restaurants/1

The path components really are part of the UI -and sometimes a very
visible part. I want mine to be intuitive and that sometimes means
nested with non-unique IDs.

Chris Cruft

unread,
Jul 8, 2007, 4:28:10 PM7/8/07
to Ruby on Rails: Core
Josh,
I grok what Daniel is trying to say, but I can't tell if you do or
not. Perhaps this will help.

/mother/273753/child/234
/father/342986/child/234
/child/234

In all of those URLs it is very clear which single resource we are
referencing: Child 234. But the URLs give very different context
information. For the first URL, I want to show a pink background, in
the second I want to show a blue background and in the last one, I
want to show a white background, to give a simple example.

Context counts.

Now if we could only get Rails to help us identify that context more
accurately, I'd be happy [warning -going slightly off topic...].

Are these two URLs presenting the same context?

/users/17/groups/2/tags
/groups/2/users/17/tags

Short of routing these URLs to different (otherwise identical)
controllers or manually inspecting the URI, does anybody know how to
differentiate them?

Sure would be nice if Rails exposed the matched route to the
controller! Perhaps an RO attribute of
ActionController::AbstractRequest set in
ActionController::Routing::RouteSet.recognize?

Evan Weaver

unread,
Jul 8, 2007, 10:01:06 PM7/8/07
to rubyonra...@googlegroups.com
Agree. some_model/1/other_model/2 is a lame way to refer to join_model/1.

Evan

On 7/7/07, Josh Peek <josh...@gmail.com> wrote:
>

Michael Koziarski

unread,
Jul 8, 2007, 10:05:14 PM7/8/07
to rubyonra...@googlegroups.com
> Agree. some_model/1/other_model/2 is a lame way to refer to join_model/1.

Putting polymorphism aside, what about:

posts/1/comments/34

Which then lets me do

@post = user.posts.find(params[:post_id])
@comment = @post.comments.find(params[:id])

Does that suck?


--
Cheers

Koz

Obie Fernandez

unread,
Jul 9, 2007, 12:27:16 AM7/9/07
to rubyonra...@googlegroups.com

No, it doesn't suck at all, and that snippet represents a Rails "best
practice", doesn't it?

Frankly, I haven't seen any compelling arguments against multi-level
nested routes yet. Not to mention that If you have public-facing URLs,
then the realities of SEO mean that the more relevant information you
can cram into your URLs the better.

Cheers,
Obie


>
>
> --
> Cheers
>
> Koz
>
> >
>

Daniel N

unread,
Jul 9, 2007, 12:33:16 AM7/9/07
to rubyonra...@googlegroups.com
On 7/8/07, Josh Peek <josh...@gmail.com> wrote:


It's getting quite large.  I've included relevant models, controllers and views, limited to an example of the purpose at hand. The index view of the clips controller. 

The only time I access clips via a nested route is by the ClipsController - index, and show methods.  Other than that I don't require the nested resources at the moment.

I'm actually very apprehensive about putting this out for public crit, but I'm more interested in how to model this properly for this project and future ones, so please be gentle ;)  There are some very messy parts in the user model associations to access clips.  The funny thing is, for all the ugliness they provide, I'm not actually using the methods anywhere yet. 

If I've left out any important aspects of the code let me know.

http://pastie.caboo.se/77228

-Daniel

Geoff B

unread,
Jul 9, 2007, 2:11:31 PM7/9/07
to Ruby on Rails: Core
1) the uri

/albums/79/tracks/219

doesn't reveal whether the underlying association between Album and
Track is has-many, has-and-belongs-to-many, or has-and-belongs-to-many-
through. I see this as an asset -- you can refactor your model
associations as business requirements change without having to rework
your uri structure.

2) even if you do have a join table -- say Book
has_many :authors, :through => :authorships -- you still might want
the uri to reference a Book and an Author, which are concrete objects.
rather than an Authorship, which is an abstract concept. In the real-
world DSL of the book trade, a customer might request more information
about a book's author, or about a particular book written by an
author, but not for more information about an "authorship."


On Jul 8, 9:01 pm, "Evan Weaver" <ewea...@gmail.com> wrote:
> Agree. some_model/1/other_model/2 is a lame way to refer to join_model/1.
>
> Evan
>

Sam Smoot

unread,
Jul 9, 2007, 11:26:32 PM7/9/07
to Ruby on Rails: Core

Not at all. The alternative implies: If you go around promoting every
2-way association (habtm) to an actual Entity, you probably want to
crack open the PoEAA and brush up a bit on Domain Model. Your object
model can be richer than your database schema. That's not a bad thing.
Trying to achieve 1:1 parity between the two seems awfully misguided.

More than that, a single authoritative URI for a particular resource
seems arbitrarily limiting. Objects don't work that way (see:
references). Your database schema doesn't work that way. What goal is
being achieved through it? Nothing at all pragmatic as far as I can
tell...

In fact, the idea that 2-way associations should be banished from your
Domain Model is entirely unique to Rails as far as my limited
experience suggests, and it certainly doesn't strike me as a good idea
at all, but more a misrepresentation of "you can" into "you should". I
might even go so far as to call the unjustified and/or indescriminate
promotion of habtm relationships to has_many => :through as a "code
smell", though I personally can't stand the phrase. :-)

Josh Peek

unread,
Jul 10, 2007, 1:18:55 AM7/10/07
to Ruby on Rails: Core
Decided to take some action with a Rails ticket.

http://dev.rubyonrails.org/ticket/8932

Josh Knowles

unread,
Jul 10, 2007, 2:55:28 AM7/10/07
to rubyonra...@googlegroups.com
On 7/7/07, Josh Peek <josh...@gmail.com> wrote:
I've seen a ton of tickets of people trying to extend polymorphic_path([...]) to do
everything for them when a proper work around with named routes will
do.


You are assuming that you know what the route will be.  When developing a controller to handle a polymorphic resource its quite often that you don't know the type of the objects, thus polymorphic_path([@parent, @child]) becomes much cleaner then a nested if or case statement.

I am actively using this feature on two large scale applications which are deployed into production and it has helped me to maintain skinny polymorphic controllers.


--
Josh Knowles
joshk...@gmail.com
http://joshknowles.com

Brian Hogan

unread,
Aug 3, 2007, 12:04:53 PM8/3/07
to Ruby on Rails: Core
Forgive me for reopening an old thread, but

> posts/1/comments/34
>
> Which then lets me do
>
> @post = user.posts.find(params[:post_id])
> @comment = @post.comments.find(params[:id])

Forgive me, but I actually do think that's silly. If I really needed
to do that I'd do

@comment = Comment.find(params[:id], :include=>[:post]
@post = @comment.post

and save a hit to the database.

I'm having a really hard time wrapping my mind around the nesting,
except that the URL looks pretty. Do you really mean to say that we
should be accessing both objects that way? It seems really hackish.
When I did this without nested routes on my first project, I built
URLs this way but never used the post_id in the URL at all. Is that
wrong?

I'm just looking for some enlightenment here, not trying to be
difficult! :)

DHH

unread,
Aug 3, 2007, 12:18:05 PM8/3/07
to Ruby on Rails: Core

This is for security/data integrity reasons. When you fetch like the
example above, you can only access posts that were written by the
user. And only access comments written about that particular post. On
a blog that might not matter much, but on an application that keeps
data secret from different accounts, it's paramount.

Chris Cruft

unread,
Aug 3, 2007, 12:45:00 PM8/3/07
to Ruby on Rails: Core
Some people use the concept of resource nesting or "belongs to" to
manage security, but it is pretty one-dimensional. More robust
security systems (role-based access control, for example) have a much
richer concept of authorization than could possibly be expressed in a
request string. I love nested resources and use them a lot, but I
wouldn't have expected Rails to hold up one (simple) interpretation of
security as a justification.

I justify nested resources because they provide context information.
For example:

/users/23/groups/17/tags
/groups/17/users/23/tags

Those two URLs refer to very different things and it is the ORDERED
nesting that sets them apart. Unfortunately, Rails doesn't provide
any help with the ordering (ticket 8105) obliging me to inspect the
request in order to know which tags we are talking about.

-Chris

Brian Hogan

unread,
Aug 3, 2007, 6:01:57 PM8/3/07
to rubyonra...@googlegroups.com
Well see that's exactly why I am confused. 
I understand the data integrity thing and the security thing, but how far do you take that?

/users/1/projects/2/tasks/3/notes/4

@user.find(params[:user_id]
@project  @user.projects.find(params[:project_id]
@task = @project.tasks.find(params[:task_id]
@note = @task.notes.find(params[:id]

That just really seems to get messy. Is that really the approach you'd take? I assume you'd use some sort of includes there to reduce the db calls then, right?

Are there examples of projects that use this nesting stuff in the wild that we could actually see the code to? I'd love to figure out what I'm missing here, as I really feel like I'm not "getting" it.  In the past, for security purposes, I'd just have the user *own* everything by user_id and use that to see if someone can actually use it.

Thanks for the explanation though, this is a really good topic.

Michael Koziarski

unread,
Aug 3, 2007, 6:07:27 PM8/3/07
to rubyonra...@googlegroups.com
> Are there examples of projects that use this nesting stuff in the wild that
> we could actually see the code to? I'd love to figure out what I'm missing
> here, as I really feel like I'm not "getting" it. In the past, for security
> purposes, I'd just have the user *own* everything by user_id and use that to
> see if someone can actually use it.

But if you have a team of people who can access a project, then how
can you use user_id?

I'd expect almost all of the open source rails applications which do
this kind of security will be following association proxies to
implement their security.


--
Cheers

Koz

Michael Glaesemann

unread,
Aug 3, 2007, 6:14:39 PM8/3/07
to rubyonra...@googlegroups.com

On Aug 3, 2007, at 17:01 , Brian Hogan wrote:

> Well see that's exactly why I am confused.
> I understand the data integrity thing and the security thing, but
> how far do you take that?
>
> /users/1/projects/2/tasks/3/notes/4
>
> @user.find(params[:user_id]
> @project @user.projects.find(params[:project_id]
> @task = @project.tasks.find(params[:task_id]
> @note = @task.notes.find(params[:id]
>
> That just really seems to get messy. Is that really the approach
> you'd take? I assume you'd use some sort of includes there to
> reduce the db calls then, right?
>

AIUI, In this situation, I'd be in the notes_controller. I'd have
already set up find_user, find_project, find_task, and
find_note_by_id methods called by before_filter, e.g.,

# in application.rb
private
def find_user
@user = User.find(params[:user_id])
end

def find_project
@project = @user.projects.find(params[:project_id])
end

def find_task
@task = @project.tasks.find(params[:task_id])
end

# in notes_controller.rb
private
before_filter :find_user
before_filter :find_project
before_filter :find_task
before_filter :find_note, :except => [:index, :new, :create]

def find_note_by_id
@note = @task.notes.find(params[:id])
end

Very succinct, I believe.

Michael Glaesemann
grzm seespotcode net


Brian Hogan

unread,
Aug 3, 2007, 6:23:13 PM8/3/07
to rubyonra...@googlegroups.com
Sure. Very much so... and that's exactly how I've been doing it.  So what I understand is that it's perfectly fine to query the database that many times, because it's good for security and data integrity. I can live with that. Just wanted to make sure that was the best way to explain it to my students. Some people will surely look at the sql logs and see four separate (albeit small) queries and wonder why that's necessary, so I want to have a good answer for them.

Thanks everyone! I really appreciate it.

On 8/3/07, Michael Glaesemann <gr...@seespotcode.net> wrote:


On Aug 3, 2007, at 17:01 , Brian Hogan wrote:

> Well see that's exactly why I am confused.
> I understand the data integrity thing and the security thing, but
> how far do you take that?
>
> /users/1/projects/2/tasks/3/notes/4
>
> @user.find(params[:user_id]
> @project  @ user.projects.find(params[:project_id]

> @task = @project.tasks.find(params[:task_id]
> @note = @task.notes.find(params[:id]
>
> That just really seems to get messy. Is that really the approach
> you'd take? I assume you'd use some sort of includes there to
> reduce the db calls then, right?
>

AIUI, In this situation, I'd be in the notes_controller. I'd have
already set up find_user, find_project, find_task, and
find_note_by_id methods called by before_filter, e.g.,

# in application.rb
private
def find_user
   @user = User.find(params[:user_id])
end

def find_project
   @project = @user.projects.find (params[:project_id])

Paolo Negri

unread,
Aug 3, 2007, 6:23:26 PM8/3/07
to rubyonra...@googlegroups.com
I think nested routes are quite cool and useful, specially if instead
of using numerical IDS you use codes that have a meaning for the user

so

projects/2/tasks_category/3/task/5

becomes

projects/CoolWebApp/task_categories/design/tasks/user_profile

Such a url is hackable and meaningful, it's currently supported by
rails and I'd be disappointed if it won't anymore.

that's my 0.02

Paolo

Michael Glaesemann

unread,
Aug 3, 2007, 6:36:14 PM8/3/07
to rubyonra...@googlegroups.com

On Aug 3, 2007, at 17:23 , Brian Hogan wrote:

> Sure. Very much so... and that's exactly how I've been doing it.
> So what I understand is that it's perfectly fine to query the
> database that many times, because it's good for security and data
> integrity. I can live with that. Just wanted to make sure that was
> the best way to explain it to my students. Some people will surely
> look at the sql logs and see four separate (albeit small) queries
> and wonder why that's necessary, so I want to have a good answer
> for them.

If performance were an issue, I'd benchmark it as is, then test it
using a find_by_sql. So far, performance hasn't been an issue for me.
I'd also have to figure out how to go about initializing models with
the values pulled from that find_by_sql. Premature optimization, and
all that.

MIchael Koziarski brings up an interesting point, however, and I'm
interested in hearing discussion on that as well.

Brian Hogan

unread,
Aug 3, 2007, 6:39:05 PM8/3/07
to rubyonra...@googlegroups.com
Indeed. I'd love to see examples of this proxy for authentication for teams of which he speaks. :)

On 8/3/07, Michael Glaesemann < gr...@seespotcode.net> wrote:

Tim Lucas

unread,
Aug 3, 2007, 9:08:18 PM8/3/07
to rubyonra...@googlegroups.com
On 04/08/2007, at 8:39 AM, Brian Hogan wrote:

> Indeed. I'd love to see examples of this proxy for authentication
> for teams of which he speaks. :)

/projects/3/tasks/8/notes/2

class User < ActiveRecord::Base
has_many :roles
has_many :projects, :through => :roles
end

class Project < ActiveRecord::Base
has_many :tasks
end

class Task < ActiveRecord::Base
has_many :notes
end

class NotesController < ApplicationController


before_filter :find_project
before_filter :find_task
before_filter :find_note

def show
end

protected
def find_project
@project = current_user.projects.find(params[:project_id])


end
def find_task
@task = @project.tasks.find(params[:task_id])
end

def find_note


@note = @task.notes.find(params[:id])
end

end

Notice each find is scoped using it's AR associations proxy, starting
from current_user.projects

-- tim

Brian Hogan

unread,
Aug 3, 2007, 9:30:31 PM8/3/07
to rubyonra...@googlegroups.com
ha! Of course. That makes total sense. :) Wow. Sometimes it's right there in front of you. Thanks a lot!

court3nay

unread,
Aug 3, 2007, 10:59:55 PM8/3/07
to rubyonra...@googlegroups.com
Those filters are easily memcached when you start hitting loads, and are easily stubbed in your controller spec.  You can also combine some of those calls with an :include.

Also, some of the actual find_xx methods belong in application controller.

-------
Courtenay

Hendy Irawan

unread,
Aug 5, 2007, 1:42:04 AM8/5/07
to rubyonra...@googlegroups.com
Brian Hogan wrote:
> Sure. Very much so... and that's exactly how I've been doing it. So
> what I understand is that it's perfectly fine to query the database
> that many times, because it's good for security and data integrity. I
> can live with that. Just wanted to make sure that was the best way to
> explain it to my students. Some people will surely look at the sql
> logs and see four separate (albeit small) queries and wonder why
> that's necessary, so I want to have a good answer for them.
>
> Thanks everyone! I really appreciate it.
To add, shouldn't security/authorization be implemented mostly in the
model? In Tom's Hobo, all of authorization mechanism take place in the
model. The model should know which requests (users) should be able to
access (read/update/delete) it (or parts of it, e.g. individual fields).
The controller only passes authorization requests to the model, it obeys
what the models are supposed to allow or deny.

Using polymorphic paths to be more logical and nice to look is great...
but if security is one added advantage, is it really the appropriate
place to put such (only!) security measure?

--
Hendy Irawan
www.hendyirawan.com


Manfred Stienstra

unread,
Aug 5, 2007, 8:45:29 AM8/5/07
to rubyonra...@googlegroups.com
On Aug 5, 2007, at 7:42 AM, Hendy Irawan wrote:

> To add, shouldn't security/authorization be implemented mostly in the
> model?

Depends on the level you have to authorize on. I've never written an
application where is was necessary to drop down to model level to
ensure people didn't access information they shouldn't access.

Reply all
Reply to author
Forward
0 new messages