Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to set custom expires_in #73

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ should be cached, similar to how you use them with `before_action`.

As of Rails 3.0, you can also pass `:expires_in` with a time
interval (in seconds) to schedule expiration of the cached item.
You can also modify the expires in by passing a symbol as `:set_expires_in`.
This is useful if you need different expire times in your action or if you use
a concern to set `caches_action` and your controllers must have different
expire times.

The following example depicts some of the points made above:

Expand All @@ -86,6 +90,9 @@ class ListsController < ApplicationController
# expire cache after an hour
caches_action :archived, expires_in: 1.hour

# custom expire cache
caches_action :archived, expires_in: :set_expires_in

# cache unless it's a JSON request
caches_action :index, unless: -> { request.format.json? }

Expand All @@ -106,6 +113,14 @@ class ListsController < ApplicationController
list_url(params[:id])
end
end

def set_expires_in
if params[:user_id]
2.hours
else
48.hours
end
end
end
```

Expand Down
12 changes: 7 additions & 5 deletions lib/action_controller/caching/actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def caches_action(*actions)
options = actions.extract_options!
options[:layout] = true unless options.key?(:layout)
filter_options = options.extract!(:if, :unless).merge(only: actions)
cache_options = options.extract!(:layout, :cache_path).merge(store_options: options)
cache_options = options.extract!(:layout, :cache_path, :expires_in).merge(store_options: options)

around_action ActionCacheFilter.new(cache_options), filter_options
end
Expand Down Expand Up @@ -147,22 +147,24 @@ def expire_action(options = {})

class ActionCacheFilter # :nodoc:
def initialize(options, &block)
@cache_path, @store_options, @cache_layout =
options.values_at(:cache_path, :store_options, :layout)
@cache_path, @cache_layout, @expires_in, @store_options =
options.values_at(:cache_path, :layout, :expires_in, :store_options)
end

def around(controller)
cache_layout = expand_option(controller, @cache_layout)
path_options = expand_option(controller, @cache_path)
expires_in = expand_option(controller, @expires_in)
store_options = @store_options.merge(expires_in: expires_in)
cache_path = ActionCachePath.new(controller, path_options || {})

body = controller.read_fragment(cache_path.path, @store_options)
body = controller.read_fragment(cache_path.path, store_options)

unless body
controller.action_has_layout = false unless cache_layout
yield
controller.action_has_layout = true
body = controller._save_fragment(cache_path.path, @store_options)
body = controller._save_fragment(cache_path.path, store_options)
end

body = render_to_string(controller, body) unless cache_layout
Expand Down
78 changes: 78 additions & 0 deletions test/caching_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ def call(controller)
end
end

class ExpiresIn
def call(controller)
1.hour
end
end

class ActionCachingTestController < CachingController
rescue_from(Exception) { head 500 }
rescue_from(ActionController::UnknownFormat) { head :not_acceptable }
Expand All @@ -36,6 +42,8 @@ class ActionCachingTestController < CachingController
caches_action :edit, cache_path: ->(c) { c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
caches_action :custom_cache_path, cache_path: CachePath.new
caches_action :symbol_cache_path, cache_path: :cache_path_protected_method
caches_action :custom_expires_in, expires_in: ExpiresIn.new
caches_action :symbol_expires_in, expires_in: :expires_in_protected_method
caches_action :with_layout
caches_action :with_format_and_http_param, cache_path: ->(c) { { key: "value" } }
caches_action :with_symbol_format, cache_path: "http://test.host/action_caching_test/with_symbol_format"
Expand Down Expand Up @@ -102,6 +110,8 @@ def simple_runtime_error
alias_method :destroy, :index
alias_method :custom_cache_path, :index
alias_method :symbol_cache_path, :index
alias_method :custom_expires_in, :index
alias_method :symbol_expires_in, :index
alias_method :layout_false, :with_layout
alias_method :with_layout_proc_param, :with_layout
alias_method :with_layout_proc_param_no_args, :with_layout
Expand All @@ -121,6 +131,16 @@ def expire_with_url_string
head :ok
end

def expire_symbol_expires_in
expire_action controller: "action_caching_test", action: "symbol_expires_in"
head :ok
end

def expire_custom_expires_in
expire_action controller: "action_caching_test", action: "custom_expires_in"
head :ok
end

def streaming
render plain: "streaming", stream: true
end
Expand Down Expand Up @@ -159,6 +179,10 @@ def cache_path_protected_method
["controller", params[:id]].compact.join("-")
end

def expires_in_protected_method
1.hour
end

if ActionPack::VERSION::STRING < "4.1"
def render(options)
if options.key?(:plain)
Expand Down Expand Up @@ -484,6 +508,60 @@ def test_cache_expiration
assert_equal new_cached_time, @response.body
end

def test_cache_expiration_with_symbol
draw do
get "/action_caching_test/symbol_expires_in", to: "action_caching_test#symbol_expires_in"
get "/action_caching_test/expire", to: "action_caching_test#expire_symbol_expires_in"
end

get :symbol_expires_in
assert_response :success
cached_time = content_to_cache

get :symbol_expires_in
assert_response :success
assert_equal cached_time, @response.body

get :expire_symbol_expires_in
assert_response :success

get :symbol_expires_in
assert_response :success
new_cached_time = content_to_cache
assert_not_equal cached_time, @response.body

get :symbol_expires_in
assert_response :success
assert_equal new_cached_time, @response.body
end

def test_cache_expiration_with_custom_object
draw do
get "/action_caching_test/symbol_expires_in", to: "action_caching_test#custom_expires_in"
get "/action_caching_test/expire", to: "action_caching_test#expire_custom_expires_in"
end

get :custom_expires_in
assert_response :success
cached_time = content_to_cache

get :custom_expires_in
assert_response :success
assert_equal cached_time, @response.body

get :expire_custom_expires_in
assert_response :success

get :custom_expires_in
assert_response :success
new_cached_time = content_to_cache
assert_not_equal cached_time, @response.body

get :custom_expires_in
assert_response :success
assert_equal new_cached_time, @response.body
end

def test_cache_expiration_isnt_affected_by_request_format
draw do
get "/action_caching_test", to: "action_caching_test#index"
Expand Down