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 -~----------~----~----~----~------~----~------~--~---