Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

weird behavior on expire_page when you are running under namespace

#5368

[This ticket is not a bug, somebody could close it?]

Today when I'm testing Rails 3.0 I found a behavior that I think is bug.

If you have a blog with an admin and public area like below:

  namespace :admin do
    resources :posts
  end

  resources :posts

And create a sweeper like:


class PostSweeper < ActionController::Caching::Sweeper
  def after_save(resource)
    expire_cache(resource)
  end

  def after_destroy(resource)
    expire_cache(resource)
  end

  def expire_cache(resource)
    expire_page :controller => "posts", :action => "show"
  end
end

If you set this sweeper in Admin::PostsController and do a change in the post from Admin namespace Rails will try to expire:

/developer/app/public/admin/posts/1-rails-3-0-rc.html

And not:

/developer/app/public/posts/1-rails-3-0-rc.html

When I look the code of expire_page I found this:

http://apidock.com/rails/ActionController/Caching/Pages/ClassMethod...

This method will use the URI to set the path for the file which ends with the weird behavior above. Don't you guy think this is a bug?

Reported by Daniel Lopes · August 12th, 2010 @ 10:18 PM

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Daniel Lopes
    Daniel Lopes

    To force Rails to don't use admin in path what I did was:

    expire_page :controller => "/posts", :action => "show", :only_path => true

    But "/posts" is as strange for a controller name. Don't you think?

    August 12th, 2010 @ 10:24 PM

  2. Andrea Campi
    Andrea Campi
    • Tag changed from rails3.0rc to rails3

    -1 I'm not sure why do you think this is a bug; taking the namespace in consideration sounds like the only reasonable behavior to me.

    October 17th, 2010 @ 02:29 PM

  3. Daniel Lopes
    Daniel Lopes

    Andrea, I didn't said anything about the Admin namespace in the Sweeper. That is the reason why I think this is undesired. What I think is the right thing to expire the admin posts is:

    expire_page :controller => 'admin/posts', :action => 'index'

    But expire the admin when I want to expire the public controller, for me, is strange/

    October 19th, 2010 @ 02:36 PM

  4. Andrea Campi
    Andrea Campi

    The Sweeper itself may not be in the Admin namespace, but you are assigning it to the @Admin::PostsController@; when #expire_page is invoked, it invoked @#url_for@, which will take the controller namespace into consideration to build the cache path.
    That sounds consistent to the way #url_for works.

    October 19th, 2010 @ 10:09 PM

  5. Daniel Lopes
    Daniel Lopes

    Actually I any place I reference the admin namespace in the sweeper, neither in the controllers. The sweeper will expire the Admin controller without I said to do that.

    October 20th, 2010 @ 02:04 PM

  6. Andrea Campi
    Andrea Campi

    Your controller is named Admin::PostsController. That's all the namespacing Rails needs to see.

    If that's not the case, you need to show more of your controllers, otherwise there's no way I can guess what you mean.

    October 20th, 2010 @ 04:27 PM

  7. Daniel Lopes
    Daniel Lopes

    I attached an app for the example. In the source folder I have a PostsController and an Admin::PostsController. My admin calls the cache_sweeper method and say to dispatch it in create and update.

    My Sweeper observes the Post model and in the right callback it calls:

    expire_page :controller => "posts", :action => "show", :only_path => true

    But calling just posts in the expire_page and not admin/posts will expire admin/posts. For me it's against of the principle of least surprise. Rails inferrers that I want to expire the admin just because the controller that call cache_sweeper is in Admin namespace even when I say explicitly that the controller is just posts?

    For it's a strange.

    Take a look in the app attached.

    October 20th, 2010 @ 11:50 PM

  8. Andrea Campi
    Andrea Campi

    But calling just posts in the expire_page and not admin/posts will expire admin/posts. For me it's against of the principle of least surprise. Rails inferrers that I want to expire the admin just because the controller that call cache_sweeper is in Admin namespace even when I say explicitly that the controller is just posts?

    Yes, that's what I was trying to tell you, sorry if I didn't make it clear.

    Personally, I don't find it confusing at all, it's exactly how I would expect it to work. For instance, that's how link_to works:

    link_to 'test', :controller => "posts", :action => "index} # <a href="/admin/posts">test</a>
    
    link_to 'test', :controller => "/posts", :action => "index} # <a href="/posts">test</a>
    

    If expire_page and link_to were to build different URLs, now that would be confusing!

    October 22nd, 2010 @ 03:44 PM

  9. Daniel Lopes
    Daniel Lopes

    Now I got what are you trying to explain. In the context of views is pretty clear when the view that call's link_to (and uses url for behind) will take his own controller as scope for the url.

    In the sweepers I don't think it's so clear that's the calling of cache_sweeper in the controller will be responsible for set the scope for the url_for. But I got what you tried to explain and looking for the point of view of a link_to you are correct.

    I will close this ticket.

    October 22nd, 2010 @ 04:09 PM

  10. Rohit Arondekar
    Rohit Arondekar
    • State changed from new to invalid
    • Importance changed from to Low

    January 27th, 2011 @ 06:36 AM