Hello, I have a question on cache expiration only working from the web, and not from the console or from a rake task. I have 2 models, Post e Comments. I have this page /archives where I list all old posts. I created a controller ''archives'', where I have a page cache (caches_page :index). I need to expire this page cache, every time a Post or Comment is created/updated/destroyed. Using sweepers, this works 100%. ( http://www.railsenvy.com/2007/2/28/rails-caching-tutorial#sweepers) The problem is that, now, I implemented spam moderation by Akismet. So when a new comment is created in the database, it gets a ''pending'' status. And there''s a rake task that runs every x minutes, in order to check all ''pending'' comments against the Akismet database, and only then comments earn an ''approved'' or ''spam'' status. And it''s only then that I should expire the /archives page. So I need to expire a cached page, from something that happens outsite a controller. And it seems the only situation a sweeper works is when the event is triggered by the web. If I open the console, add a new comment to a post, nothing happens (ok!). And now I run the Akismet check, and assuming it gives the comment an ''approved'' status, the cache is not expired, when it should be. I tried to use Observers, from the Rails docs ( http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=M001871&name=observe ). In environment.rb I added the line: config.active_record.observers :archives_observer I created the file app/models/archives_observer.rb with: class ArchivesObserver < ActiveRecord::Observer observe :post, :comment def after_save(record) expire_page(:controller => ''archives'', :action => ''index'') end end But I get an error: NoMethodError: undefined method `expire_page'' for #<ArchivesObserver:0x247eddc> I tried this also: class ArchivesObserver < ActionController::Caching::Sweeper (...) In this case, there''s no error, and it does nothing at all. The public/archives.html just stays there. I''m trying my best to avoid hacking it, using a simple File.delete :) Like the code below: # File rails/actionpack/lib/action_controller/caching/pages.rb, line 65 65: def expire_page(path) 66: return unless perform_caching 67: 68: benchmark "Expired page: #{page_cache_file(path)}" do 69: File.delete(page_cache_path(path)) if File.exist?(page_cache_path(path)) 70: end 71: end Is there a way to expire pages without having to hack it? Thanks a lot, Levy --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Feb 11, 11:14 am, "Levy Carneiro Jr." <l...-S+a/CVT+5QPMxLS5FtBHQg@public.gmane.org> wrote:> I tried this also: > > class ArchivesObserver < ActionController::Caching::Sweeper > (...) > > In this case, there''s no error, and it does nothing at all. The > public/archives.html just stays there. > > I''m trying my best to avoid hacking it, using a simple File.delete :) > Like the code below: > > # File rails/actionpack/lib/action_controller/caching/pages.rb, line 65 > 65: def expire_page(path) > 66: return unless perform_caching > 67: > 68: benchmark "Expired page: #{page_cache_file(path)}" do > 69: File.delete(page_cache_path(path)) if > File.exist?(page_cache_path(path)) > 70: end > 71: end > > Is there a way to expire pages without having to hack it?I ran into a similar issue a few days ago. If I remember correctly, if you look at what Rails is doing under the covers, you''ll see that ActionController::Caching::Sweeper subclasses will only work when called from inside a controller. Basically the "expire_page" message ends up getting intercepted by "method_missing", which tries to forward it on to a controller stored in the @controller instance variable. So if you invoke your Sweeper subclass from somewhere else (like a Rake task), that @controller variable will be nil and nothing will happen. My workaround was just to fall back to File.delete and friends. Ugly, but it works. Cheers, Wincent --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks, Vincent. I just wanted to know if there was something better. I guess I''ll resort to the File.delete and friends as you mentioned :) Regards, Levy On Sun, Feb 22, 2009 at 2:09 PM, Wincent Colaiuta <win-uEs3UDB2KWBBDgjK7y7TUQ@public.gmane.org> wrote:> > On Feb 11, 11:14 am, "Levy Carneiro Jr." <l...-S+a/CVT+5QPMxLS5FtBHQg@public.gmane.org> > wrote: > > > I tried this also: > > > > class ArchivesObserver < ActionController::Caching::Sweeper > > (...) > > > > In this case, there''s no error, and it does nothing at all. The > > public/archives.html just stays there. > > > > I''m trying my best to avoid hacking it, using a simple File.delete :) > > Like the code below: > > > > # File rails/actionpack/lib/action_controller/caching/pages.rb, line > 65 > > 65: def expire_page(path) > > 66: return unless perform_caching > > 67: > > 68: benchmark "Expired page: #{page_cache_file(path)}" do > > 69: File.delete(page_cache_path(path)) if > > File.exist?(page_cache_path(path)) > > 70: end > > 71: end > > > > Is there a way to expire pages without having to hack it? > > I ran into a similar issue a few days ago. If I remember correctly, if > you look at what Rails is doing under the covers, you''ll see that > ActionController::Caching::Sweeper subclasses will only work when > called from inside a controller. Basically the "expire_page" message > ends up getting intercepted by "method_missing", which tries to > forward it on to a controller stored in the @controller instance > variable. So if you invoke your Sweeper subclass from somewhere else > (like a Rake task), that @controller variable will be nil and nothing > will happen. > > My workaround was just to fall back to File.delete and friends. Ugly, > but it works. > > Cheers, > Wincent > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Coming in late, but this might be helpful... I''ve used this from ./ script/runner... not quite rake, but... ... require ''lib/console_app'' ... ActionController::Base.expire_page(app.user_profile_path(:id => user.username)) ... (where ''user_profile'' is a named route) On Feb 28, 2009, at 7:31 PM, Levy Carneiro Jr. wrote:> Thanks, Vincent. > > I just wanted to know if there was something better. I guess I''ll > resort to > the File.delete and friends as you mentioned :) > > Regards, > Levy > > > On Sun, Feb 22, 2009 at 2:09 PM, Wincent Colaiuta <win-uEs3UDB2KWBBDgjK7y7TUQ@public.gmane.org> > wrote: > >> >> On Feb 11, 11:14 am, "Levy Carneiro Jr." <l...-S+a/CVT+5QPMxLS5FtBHQg@public.gmane.org> >> wrote: >> >>> I tried this also: >>> >>> class ArchivesObserver < ActionController::Caching::Sweeper >>> (...) >>> >>> In this case, there''s no error, and it does nothing at all. The >>> public/archives.html just stays there. >>> >>> I''m trying my best to avoid hacking it, using a simple >>> File.delete :) >>> Like the code below: >>> >>> # File rails/actionpack/lib/action_controller/caching/pages.rb, >>> line >> 65 >>> 65: def expire_page(path) >>> 66: return unless perform_caching >>> 67: >>> 68: benchmark "Expired page: #{page_cache_file(path)}" do >>> 69: File.delete(page_cache_path(path)) if >>> File.exist?(page_cache_path(path)) >>> 70: end >>> 71: end >>> >>> Is there a way to expire pages without having to hack it? >> >> I ran into a similar issue a few days ago. If I remember correctly, >> if >> you look at what Rails is doing under the covers, you''ll see that >> ActionController::Caching::Sweeper subclasses will only work when >> called from inside a controller. Basically the "expire_page" message >> ends up getting intercepted by "method_missing", which tries to >> forward it on to a controller stored in the @controller instance >> variable. So if you invoke your Sweeper subclass from somewhere else >> (like a Rake task), that @controller variable will be nil and nothing >> will happen. >> >> My workaround was just to fall back to File.delete and friends. Ugly, >> but it works. >> >> Cheers, >> Wincent >>> >> > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---