I know dalli
(caching) is pretty powerful plugin to enhance performance for static pages.
But what about dynamic pages with pagination, which are updated quite often?
What is the correct way to set up dalli
?
One problem I've encountered for example: dalli
recognizes different params[:page] as the same page when using pagination:(
How would you guys design the system when using dalli
for both
- the page that gets updated so often
- the page that won't be updated so often
For example. I have 4 models such as User
, Community
, Topic
, and Comment(defined Polymorphic to both Community, and Topic. They can be created or shown in #show pages)
It's like
- Community > (has_many) > Topics > (has_many) > Comments
- Community > (has_many) > Comments
- All of them belongs to user(creator)
My current codes are just like this(This is quite bit long. Sorry about that)
I'm facing the pagination problem when using caching...
-------------------------------------Settings----------------------------------------
config/environments/development.rb
config.consider_all_requests_local = true
config.action_controller.perform_caching = true
config.cache_store = :dalli_store
routes.rb
resources :communities do
resources :topics do
resources :comments do
end
end
-------------------------------------Community----------------------------------------
controllers/communities_controller.rb#index&show
caches_page :show
caches_action :edit, :new
def index
....
if params[:sort] == 'new'
@communities = Community.scoped.page(params[:page]).order("created_at DESC")
elsif params[:sort] = 'popular'
@communities = Community.scoped.page(params[:page]).order("follow_count DESC")
elsif params[:sort] = 'reputation'
@communities = Community.scoped.page(params[:page]).order("reputation_count DESC")
else
@communities = Community.scoped.page(params[:page]).order("created_at DESC")
end
....
end
def show
@community = Community.find(params[:community_id])
@comments @community.comments.page(params[:page]
@topics = @community.topics.limit(10)
end
views/communities/index.html.erb
note: However, the content will be the same even if I move to next params[:page]:( It seems caching recognize different page as the same contents...
#here, the url will could be something like this example.com/communities?utf8=✓&location=14&genre=3&search=strawberry
But this is going to create gigantic petterns of the caches:(
So I want to make it work only when params[:sort] was not empty. Because, no other parameters come with when params[:sort] is not empty.
It could be like, example.com/communities?sort=new, example.com/communities?sort=popular, example.com/communities?sort=reputation
...
<% if params[:sort] %>
<% @key = "community_index_" + params[:sort] + params[:page] %>
<% cache(:controller => "communities", :action => "index", :action_suffix => @key) do %>
<%= page_entries_info(@communities, :entry_name => 'community').html_safe %>
<%= paginate @communities, :window => 4 %>
<% @communities.each do |community| %>
<%= render 'communities/community', :community => community %>
<% end %>
<% end %>
<% end %>
...
views/communities/show.html.erb
...
<% @key = params[:community_name] + "_community_show_information" %>
<% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %>
<h2>Information</h2>
<div class="CommunityInformation">
<%= render 'communities/information'%>
</div>
<% end %>
<% @key = params[:community_name] + "_community_show_wall_" + params[:page] + %>
<% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %>
<%= paginate @comments, :window => 4 %>
<h2>Topic</h2>
<div class="WallInformation">
<% @comments.eager.recent.each do |comment| %>
<%= render 'communities/comment', :comment => comment %>
<% end %>
</div>
<% end %>
<% @key = params[:community_name] + "_community_show_topics" %>
<% cache(:controller => "communities", :action => "show", :action_suffix => @key) do %>
<h2>Topic</h2>
<div class="TopicInformation">
<% @topics.eager.recent.each do |topic| %>
<%= render 'communities/topic', :topic => topic %>
<% end %>
</div>
<% end %>
...
models/community_sweeper.rb
class CommunitySweeper < ActionController::Caching::Sweeper
observe Community
def after_save(record)
expire_fragment(url_for(:action => 'index', :only_path => true) + '?????(all the caches related to the community#index)')
expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(the cache related to the particular community#show)')
end
end
end
-------------------------------------Topic----------------------------------------
controllers/topics_controller.rb#index&show
caches_page :show
caches_action :edit, :new
def index
....
@community = Community.find(params[:community_id])
@topics = @community.topics.page(params[:page]
....
end
def show
@topic = Topic.find(params[:id])
@comments = @topic.comments.page(params[:page]
end
views/topics/index.html.erb
...
<% @key = params[:community_id] + "_topic_index_" + params[:page] %>
<% cache(:controller => "topics", :action => "index", :action_suffix => @key) do %>
<%= page_entries_info(@communities, :entry_name => 'community').html_safe %>
<%= paginate @communities, :window => 4 %>
<% @communities.each do |community| %>
<%= render 'communities/community', :community => community %>
<% end %>
<% end %>
<% end %>
...
views/topics/show.html.erb
...
<% @key = params[:community_name] + "_topic_show_" + params[:id] + "_comments" + params[:page] %>
<% cache(:controller => "topics", :action => "show", :action_suffix => @key) do %>
<%= paginate @comments, :window => 4 %>
<%= page_entries_info(@comments, :entry_name => 'comment').html_safe %>
<h2>Comment</h2>
<div class="CommentInformation">
<% @comments.each do |comment| %>
<%= render 'topics/comment', :comment => comment %>
<% end %>
</div>
<% end %>
...
models/topic_sweeper.rb
class TopicSweeper < ActionController::Caching::Sweeper
observe Topic
def after_save(record)
expire_fragment(url_for(:action => 'index', :only_path => true) + '?????(all the caches related to the topic#index)')
expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(the cache related to the particular topic#show)')
end
end
-------------------------------------Comment----------------------------------------
models/comment_sweeper.rb
class CommentSweeper < ActionController::Caching::Sweeper
observe Comment
def after_save(record)
expire_fragment(url_for(:action => 'index', :only_path => true) + '?????(all the caches related to the topic#index)')
expire_fragment(url_for(:action => 'show', :only_path => true) + '?????(the cache related to the particular topic#show)')
end
end