I have a controller action that has page caching, and I made a sweeper that calls expire_page with the controller and the action specified...
The controller action renders a js.erb template, so I am trying to ensure that expire_page deletes the .js file in public/javascripts, which it is not doing.
class JavascriptsController < ApplicationController
caches_page :lol
def lol
#lol = Lol.all
end
end
class LolSweeper < ActionController::Caching::Sweeper
observe Lol
def after_create(lol)
puts "lol!!!!!!!"
expire_page(:controller => "javascripts", :action => "lol", :format => 'js')
end
end
... So, I visit javascripts/lol.js and I get my template rendered.. I verified that public/javascripts/lol.js exists... I then create a new Lol record, and I see "lol!!!!!!!!!" meaning the after_create observer method is triggered, but expire_page is doing nothing...
According to RailsGuides: 'Page caching ignores all parameters.' I think I had similar problem while working on cashing .xml responses: I would write the cache for /lol.xml, but was trying to expire cache for /lol (write and expire operations can be seen in the server log). The way I made it work: I made the cache "format-agnostic" like this:
cashes_page :lol, :cache_path => Proc.new { |controller| controller.params.delete_if {|k,v| k == "format"} }
and expire in the sweeper like this:
expire_page(:controller => "javascripts", :action => "lol")
It solved my problem. Also, as a note, shouldn't your lol action be called lols? Good luck.
I tried solution form Simon's answer and it didn't work for me. The solution that worked was:
expire_page('javascripts/lol.js')
Related
Having a controller handling rendering of large XML feeds
module Spree
class FeedsController < Spree::StoreController
...
caches_action :products_out
cache_sweeper FeedSweeper
# XML feed in format of `xxxxxxx.com'
def products_out
#products = Product.all
respond_to do |format|
format.xml
end
end
end
Bellow is the corresponding sweeper's sublass:
module Spree
class FeedSweeper< ActionController::Caching::Sweeper
observe Product
def after_update(product)
# cache_configured? is nil, #controller is nil here, why ?
expire_action(:controller => :feeds,
:action => :products_out,
:format => :xml)
end
end
Above Spree::FeedSweeper is called when Spree::Product gets updated, however it seems expire_action silently dies and cache won't get invalidated.
Can somebody explain the issue ? Even better suggest some solution ?
Thanks.
Which Rails version are you using? expire_action seems to be deprecated after Rails 3.2.14.
Maybe you can try to find out the key then directly clear it with Rails.cache.delete(key).
We use dalli gem w/memcached. The following code caches Foo objects paginated across multiple pages. We are able to cache Foo(s) when we are in a certain page (say 2 or 10 or 15). But when I modify a Foo in page 15 (say Foo-150), we clear the cache for all the objects using the method in FooSweeper. after_save method is being called when the above
action happens, but the cache is not getting cleared for all pages and reflects the older values for the requested page.
Is there any mistake in the code snippet given below.
My controller looks like this..
class FooController
...
caches_action :index, cache_path: proc { |c| c.params.except(:_).merge(format: request.format) }
...
My sweeper code looks like this..
class FooSweeper < ActionController::Caching::Sweeper
observe :foo
def after_save(foo)
expire_cache(foo)
end
def before_destroy(foo)
expire_cache(foo)
end
def expire_cache(foo)
expire_action(:controller => 'foos', :action => 'index')
expire_action(:controller => 'foos', :action => 'index', :format => 'text/html')
end
end
Your controller is calles Foo, but you call controller: 'foos' from your sweeper. It could be the reason why your cache is not properly cleared.
You can fix this by changing foos to foo.
I'm using the acts_as_votable and devise gems in Rails 3.2.11 and I'm trying to automatically have the user who created an item vote it up after it's created. Sounds simple, right? I have a vote_up method in my controller and I've tried this:
after_filter :vote_up, :only => :create
Yet alas, it does nothing. I know the vote_up method isn't broken, because it works perfectly whenever it's called from the view.
Any ideas?
Edit: The vote_up method in my controller:
def vote_up
#skill_relationship = SkillRelationship.find(params[:id])
if current_user.voted_up_on? #skill_relationship then
#skill_relationship.unliked_by :voter => current_user
else
#skill_relationship.liked_by current_user
end
respond_to do |format|
format.js { render :action => "vote" }
end
end
I would also be OK with just running the line #skill_relationship.unliked_by :voter => current_user or something similar directly in my create method (which I've also tried, to no avail).
This is from quite some time ago, but if anyone else stumbles upon it, just add something like this after the model is saved in the create action:
current_user.likes #skill_relationship
I have an offline rake job that updates my models. When that happens, I want to expire the :show action for that model.
# in lib/models/my_model.rb
after_update :expire_cache
def expire_cache
expire_action :controller => :my_models, :action => :show, :id => self
end
This doesn't work because expire_action isn't available in the model. Calling ActionController.new.expire_action gives me a lot of weird route issues, which is reasonable since none of the route logic is hooked up.
I think the common way to expire_action is with a sweeper, but that doesn't work because my model is not updated through controller actions.
NOTE: I feel like I may be using caching the wrong way since I can't find an answer to this anywhere.
You're looking for an ActionController Sweeper. You can find the official Rails documentation on how to implement them here, but likely you want something like this:
class MyModelSweeper < ActionController::Caching::Sweeper
observe MyModel
def after_update(my_model)
expire_action :controller => :my_models, :action => :show, :id => my_model
end
end
I'm having some issues with Sweepers and Caching in Rails.
The .html file in /cache is being generated on first view.
The Sweeper action is being called when needed.
However, the sweeper action is not deleting the .html page from /cache
The code below is stripped down from my /controllers and /sweepers directory. the puts lines both log, so I know that we're executing fine -- the expire command just doesn't seem to delete the file.
anyone have an idea where i can lool ?
class WidgetsController < ApplicationController
cache_sweeper :widget_sweeper
caches_page :help
def help
render :template => '/widgets/help.html'
end
end
class WidgetSweeper < ActionController::Caching::Sweeper
observe HelpPage
def after_save(record)
puts "record "
puts record.inspect
expire_page(:controller => 'widgets', :action => 'help')
puts "ok!"
end
end
Are you just testing this by manipulating some HelpPage records in the console? It looks like you have to affect the changes in a controller.
I made a test app using the code you supplied above and ran it with caching enabled. I created some new HelpPage records in the rails console, and I got the two log messages but no page expiration.
However, when I created a new HelpPage in a controller, I did get the page expiration as expected.