Ruby Forum Rails-core > polymorphic_url and namespaces

Posted by Sven Fuchs (Guest)
on 09.05.2008 16:54
(Received via mailing list)
So, this has been discussed in great length before, see [1], but to me
the solution [2] feels quite incomplete, so I thought I'd bring this
up again.

Currently polymorphic_url needs to be passed a namespace explicitely
to have it delegate to a namespaced url generation method:

   map.resources :articles
   map.namespace :admin do |admin|
     admin.resources :articles
   end

Now, no matter where link_to(@article) is called it always will
delegate to article_path.

 From my perspective it would make a lot of sense to have
polymorphic_url to

- delegate to article_path when we're outside of the namespace but
- delegate to admin_article_path when we're inside of the namespace

It has been argued in [1] that polymorphic_url just does its "best
guess" and thus the current behaviour was correct at that time.

But I find it hard to subscribe to that. With resources controllers,
views, routes etc. obviously are grouped and conceptually belong
together, so the "best guess" for link_to(@article) from within (e.g.)
views/admin/show would IMO to delegate to admin_article_path, not
article_path. Put differently I think that these url_helpers & co
should default to the current resource (including the namespace) we're
working with, not an more or less arbitrary resource like it's the
current behaviour.

Now, there currently doesn't seem to be way to determine the current
namespace in a controller (and thus in polymorphic_url). From looking
at routes building/recognition etc. it might not be too hard to pass
the :namespace option from the route definition to the route (while
building it) and then to the controller instance (after recognition).

Am I missing something obvious?


[1] http://www.ruby-forum.com/topic/111136
[2] http://dev.rubyonrails.org/ticket/8640

--
sven fuchs      svenfuchs@artweb-design.de
artweb design    http://www.artweb-design.de
grünberger 65    + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin    + 49 (0) 171 - 35 20 38 4 (mobile)
Posted by Michael Koziarski (Guest)
on 10.05.2008 05:02
(Received via mailing list)
>  From my perspective it would make a lot of sense to have
> polymorphic_url to
>
> - delegate to article_path when we're outside of the namespace but
> - delegate to admin_article_path when we're inside of the namespace
>
> It has been argued in [1] that polymorphic_url just does its "best
> guess" and thus the current behaviour was correct at that time.

It definitely does it's 'best guess',  but that's not to say it's best
is good enough.  The all blacks did their best in the recent rugby
world cup, the french still kicked their ass :).

> Now, there currently doesn't seem to be way to determine the current
> namespace in a controller (and thus in polymorphic_url). From looking
> at routes building/recognition etc. it might not be too hard to pass
> the :namespace option from the route definition to the route (while
> building it) and then to the controller instance (after recognition).
>
> Am I missing something obvious?

We could pass the namespace option in the routes, however what about
just regular controllers in modules.  Are they in a namespace?  Also,
things like render :partial and friends need to be aware of these
namespaces.

Definitely sounds like something that'd be good to clean up and if
you're interested in hacking on it, let us know. Hopefully we'll have
a 2.1 branch out of the way soon and can get to work on the backlog.

--
Cheers

Koz
Posted by Sven Fuchs (Guest)
on 10.05.2008 11:44
(Received via mailing list)
On 10.05.2008, at 05:01, Michael Koziarski wrote:
> It definitely does it's 'best guess',  but that's not to say it's best
> is good enough.

Sure! I hope my phrasing didn't sound harsh.

> The all blacks did their best in the recent rugby
> world cup, the french still kicked their ass :).

Hehe. I have no idea what you are talking about ;D

> We could pass the namespace option in the routes, however what about
> just regular controllers in modules.  Are they in a namespace?

When we pass the namespace option to the route we can also pass it
back from #recognize and set it to the current controller instance
(like params). So the controller would always know if it has been
instantiated for a request through a "namespaced" route or not.

Thus the user would have full control: if he maps a route to a
controller inside of a module but doesn't use the namespace option in
the route definition the controller would end up with no namespace set
for that request. If the same controller is also mapped with a
namespaced route and that route recognizes a request path the
controller would have a namespace set.

When the controller can access the current namespace it can use it in
#polymorphic_url to do a "better guess".

> Also,
> things like render :partial and friends need to be aware of these
> namespaces.

By that you mean calls to polymorphic_url from within partials?
Definitely. I believe that should work the same way as above.

> Definitely sounds like something that'd be good to clean up and if
> you're interested in hacking on it, let us know. Hopefully we'll have
> a 2.1 branch out of the way soon and can get to work on the backlog.

Ok, fine. I'll have a stab at that.

I guess it makes more sense to discus implementation specific
questions on #rails-contrib.


--
sven fuchs      svenfuchs@artweb-design.de
artweb design    http://www.artweb-design.de
grünberger 65    + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin    + 49 (0) 171 - 35 20 38 4 (mobile)
Posted by Mislav MarohniÄ? (mislav)
on 10.05.2008 15:29
(Received via mailing list)
Sven,

+1 for namespace awareness. I've been making my own helpers to wrap 
route
calls and inject the current namespace and I can tell it's a pain (it's
certainly bug-prone). If the framework handled this, it would be much
better.


On Sat, May 10, 2008 at 11:43 AM, Sven Fuchs 
<svenfuchs@artweb-design.de>
Posted by Michael Koziarski (Guest)
on 11.05.2008 08:15
(Received via mailing list)
> Sven,
>
> +1 for namespace awareness. I've been making my own helpers to wrap route
> calls and inject the current namespace and I can tell it's a pain (it's
> certainly bug-prone). If the framework handled this, it would be much
> better.

Sounds like we have a few motivated contributors here, looking forward
to watching it take shape in irc :)




--
Cheers

Koz
Posted by Sven Fuchs (Guest)
on 11.05.2008 12:10
(Received via mailing list)
> Sounds like we have a few motivated contributors here, looking forward
> to watching it take shape in irc :)

Ok, I've implemented what I believe is a sane option here:

http://github.com/svenfuchs/rails/commits/master/

There are a couple of things to discuss though and none of you (koz,
mislav) is on #rails-contrib right now so I thought I'd ask here
instead.

Most importantly, after storing the namespace option in the route and
then passing it back from Route#recognize_path where should it be
stored in the controller layer?

I first thought that the best option is to set it on the controller
instance. After studying the code more thoroughly I now think that
another sane option is to just store it in the params hash.

Storing it in the controller instance would require to

- either temporarily store it in the params hash in
Route#recognize_path and then delete if from there in
Dispatcher#handle_request or even ActionController::Base#process
(ugly, but doesn't require to change the involved method apis that
pass the params hash)
- or change the return value apis of at least Route#recognize_path and
RouteSet#recognize to return something like [params, route] or
[params, namespace] (also noisy, but less ugly, also requires to
change lots of tests)

Storing it in the params hash would require the fewest changes
allover. We'd just stick the namespace to params in
Route#recognize_path and can then access that in polymorphic_url (and
everywhere else in the controller layer).

(Another option would be to store it in the Request object, but
there's no similar information stored so far.)

I've opted for the last option for now, but of course that exposes
another key in the params hash. What do you think about that? Looking
at the existing keys like :controller and :action the additional
key :namespace would IMO make a lot sense here anyways because that's
all stuff that's defined in the routes.

Hope to catch any of you on IRC, please ping me :)

--
sven fuchs      svenfuchs@artweb-design.de
artweb design    http://www.artweb-design.de
grünberger 65    + 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin    + 49 (0) 171 - 35 20 38 4 (mobile)