在你的 Rails App 中开启 ETag 加速页面载入同时节省资源
Last active
October 13, 2015 22:28
-
-
Save jhjguxin/4265619 to your computer and use it in GitHub Desktop.
improve the performance of your Rails app(through cache some helper methods), some tips wich from BBTangCMS ...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<% if model_class.present? and (mod_newest_collection = cache_helper(:mod_newest_count,{},model_class)).present?%> | |
<i><%= "目前共有#{model_class.model_name.human}: #{model_class.count}。其中"%><%= raw mod_newest_collection.collect{|item| distance_of_time_in_words_to_now(item.first) << "之内新增#{model_class.model_name.human}" << "#{item.last}" if item.present?}.compact.join(", ") << "。" %></i> | |
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
class ApplicationController < ActionController::Base | |
=begin | |
# 会导致 stale? 失效 | |
def fresh_when(opts = {}) | |
opts[:etag] ||= [] | |
# 保证 etag 参数是 Array 类型 | |
opts[:etag] = [opts[:etag]] if !opts[:etag].is_a?(Array) | |
# 加入页面上直接调用的信息用于组合 etag | |
opts[:etag] << current_user | |
# Config 的某些信息 | |
opts[:etag] << @meta_keywords | |
opts[:etag] << @meta_description | |
# 所有 etag 保持一天 | |
opts[:etag] << Date.current | |
super(opts) | |
end | |
=end | |
def fresh_when(record_or_options, additional_options = {}) | |
if record_or_options.is_a? Hash | |
record_or_options[:etag] = record_or_options_etag(record_or_options[:etag]) | |
else | |
record = record_or_options_etag record_or_options | |
additional_options = { :etag => record , :last_modified => record.try(:updated_at) }.merge(additional_options) | |
end | |
puts "#{ActiveSupport::Cache.expand_cache_key record_or_options[:etag]}" if Rails.env.development? | |
super record_or_options,additional_options | |
end | |
private | |
def record_or_options_etag(etag,default_etag=[]) | |
default_etag ||= [current_user, @meta_keywords, @meta_description, Date.current,flash.to_hash].compact | |
if etag.is_a?(Array) or etag.respond_to? :to_a | |
record = etag.try(:to_a).concat default_etag | |
else | |
record = default_etag << etag | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
module ApplicationHelper | |
=begin | |
def cache_helper(method_name, cache_params = {:expires_in => 30.minutes},*method_params);end | |
=> nil | |
def cache_helper(method_name,*method_params,cache_params);end | |
=> nil | |
=end | |
# a common helper method to cache the return value of specil helper | |
# usage | |
def cache_helper(method_name, cache_params = {:expires_in => 30.minutes},*method_params) | |
cache_params = {:expires_in => 30.minutes} if cache_params.empty? | |
if method_name.present? and self.respond_to? method_name | |
cache_keys = "#{method_name}_" << method_params.collect{|v| "#{v}"}.join("&") << cache_params.collect{|k,v| "#{k.to_s}_#{v}"}.join("&") | |
if Rails.cache.read("#{cache_keys}").nil? | |
#send(:foo, *args) | |
# same as: send(:foo, "abc") | |
method_cache = self.send method_name, *method_params | |
Rails.cache.write("#{cache_keys}" ,method_cache , cache_params) | |
end | |
Rails.cache.read("#{cache_keys}") | |
else | |
puts "no method defined #{method_name}, or something wrong unknow" | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
module CommonHelper | |
def model_columns_collection(model_class = nil, whitelist = false,except =[] ) | |
if (model_class.method_defined? :columns) or (model_class.respond_to? :columns) | |
if whitelist | |
#model_class.columns.collect{|column| [model_class.human_attribute_name(column.name),column.name]} | |
#model_class.attribute_names.collect{|column| [model_class.human_attribute_name(column),column]} | |
model_columns_list = model_class.accessible_attributes.collect{|column| [model_class.human_attribute_name(column),column]} | |
else | |
model_columns_list = model_class.column_names.collect{|column| [model_class.human_attribute_name(column),column]} | |
end | |
else | |
if (model_class.method_defined? :fields) or (model_class.respond_to? :fields) | |
model_columns_list = model_class.fields.to_a.collect{|field| [model_class.human_attribute_name(field.first),field.first]} | |
end | |
end | |
if (except.class == Array) and except.present? | |
#model_columns_list.collect! | |
model_columns_list.collect!{|col| col unless except.include? col[1]} | |
end | |
return model_columns_list | |
end | |
def version_log( t_count = "1", unit = "minute" ) | |
#h ||= 1 | |
s_time = t_count.to_i.send(unit).send("ago") if t_count.to_i > 0 | |
s_time ||= 1.minute.ago | |
lastest_logs = Version.where(:created_at => s_time .. Date.tomorrow) | |
#count.to_i.send("hours").send("ago") if count.to_i > 0 | |
lastest_logs.collect{|l| "#{distance_of_time_in_words_to_now(l.created_at, include_seconds = true)} #{l.whodoit}," + I18n.t("helpers.events.#{l.event}") + "#{l.item_type.classify.constantize.model_name.human.pluralize}" + "'#{l.item}'"} | |
end | |
def newest_obj(mod = "",conditions = [], t_count = "1", unit = "minute") | |
#User.where("id != ?", exclude_ids) | |
if mod.present? | |
mod = mod.classify.constantize if mod.class == String | |
s_time = t_count.to_i.send(unit).send("ago") if t_count.to_i > 0 | |
s_time ||= 1.minute.ago | |
mod_list = mod.where(conditions) | |
mod_list.where(:created_at => s_time .. Date.tomorrow) if mod_list.present? | |
end | |
end | |
def obj_range(mod="",s_time = nil,e_time = nil) | |
if mod.present? and s_time.present? | |
mod = mod.classify.constantize if mod.class == String | |
e_time ||= Date.tomorrow | |
mod.where(:created_at => s_time .. e_time) | |
else | |
[] | |
end | |
end | |
def obj_range_count(mod="",s_time = nil,e_time = nil) | |
obj_range(mod,s_time,e_time).count | |
end | |
def mod_newest_count(mod="") | |
if mod.present? | |
mod = mod.classify.constantize if mod.class == String | |
[1.days.ago, 2.days.ago, 3.days.ago, 1.weeks.ago, 1.month.ago,3.month.ago].collect{|s_t| [s_t, mod.where(:created_at => s_t .. DateTime.now).count]} | |
end | |
end | |
def user_newest_count | |
#time_range.collect{|s_t| [s_t, pick_the_users_special(s_t).count, regist_sources.collect{|source| {source => pick_the_users_special(s_t,source).count}}]} | |
if Rails.cache.read("user_newest_count_cache").nil? | |
#regist_sources = ["sina", "tqq", "qq_connect", "mmbkoo"] << "straight" | |
regist_sources = ["sina", "tqq", "qq_connect", "mmbkoo"] | |
time_range = [1.days.ago, 2.days.ago, 3.days.ago, 1.weeks.ago, 1.month.ago,3.month.ago] | |
#time_range = time_range[0..1] unless Rails.env.production? | |
#FIXME 直接注册 不能链式调用 | |
result = time_range.collect{|s_t| [s_t, pick_the_users_special(s_t).count, regist_sources.collect{|source| {source => pick_the_users_special(s_t,source).count}}]} | |
Rails.cache.write("user_newest_count_cache" ,result , :expires_in => 30.minutes) | |
end | |
Rails.cache.read("user_newest_count_cache") | |
end | |
def pick_the_users_special(time,source = nil) | |
if time.class.name.eql? "Time" | |
set_cache_name = '' | |
#cache = ActiveSupport::Cache::MemoryStore.new | |
#cache = Rails.cache.new | |
if source.present? | |
set_cache_name = "#{source}_#{time.to_date.to_s.gsub('-',"_")}" | |
if Rails.cache.read("#{set_cache_name}").nil? | |
# undefined class/module Authorization | |
#self.instance_variable_set "@#{set_cache_name}", Rails.cache.fetch("#{set_cache_name}", :expires_in => 24.hours) { User.where(:created_at => time .. DateTime.now).send("#{source}_user_ids") } | |
result = User.where(:created_at => time .. DateTime.now).send("#{source}_user_ids") | |
Rails.cache.write("#{set_cache_name}" ,result , :expires_in => 24.hours) | |
end | |
else | |
set_cache_name = "users_#{time.to_date.to_s.gsub('-',"_")}" | |
#if !(self.instance_variable_get("@#{set_cache_name}").present?) | |
if Rails.cache.read("#{set_cache_name}").nil? | |
result = User.where(:created_at => time .. DateTime.now) | |
Rails.cache.write("#{set_cache_name}" ,result , :expires_in => 24.hours) | |
end | |
end | |
return Rails.cache.read("#{set_cache_name}") | |
end | |
end | |
#mod = "user" , unit inside %w(day month year week) | |
def obj_group_by_time(mod = "",unit= nil) | |
unit ||= "day" | |
can_units = %w(day month year week) | |
if mod.present? and mod.classify.class_exists? and (can_units.include? unit) | |
mod = mod.classify.constantize if mod.class == String | |
mod.all.group_by{|u| u.created_at.send("beginning_of_#{unit}")} | |
else | |
[] | |
end | |
end | |
def obj_group_by_time_count(mod="",unit= "day") | |
obj_group_by_time(mod,unit).collect{|u| [u.first,u[1].count]} | |
end | |
def obj_group_by_time_summary(mod = "",unit = "day", format = "short" ) | |
objs = obj_group_by_time_count(mod,unit) | |
if objs.present? | |
objs.collect{|u| [time_tag(u[0].to_date,:format=> format.to_sym),u[1]] } | |
end | |
end | |
def obj_tips(obj_list=[]) | |
if obj_list.present? | |
#[Knowledge,Question].collect{|m| m.send(:last).send(:created_user)} | |
obj_list.collect{|obj| "#{timeago_tag_content(obj.created_at)} #{obj.send(:created_user)}," + I18n.t("helpers.events.create") + "#{obj.class.model_name.human.pluralize}" + "'#{obj}'"} | |
else | |
puts "no obj get ..." | |
end | |
end | |
def lastest_logs | |
logs = version_log.present? ? version_log : [] | |
# User.where(" id IN (?) ",User.internal_user_ids).count | |
ids = User.internal_user_ids | |
questions = newest_obj(mod="Question",conditions= [" created_by NOT IN (?) ",ids]) | |
question_logs = obj_tips(questions) if questions.present? | |
logs.concat(question_logs) if question_logs.present? | |
logs | |
end | |
def get_tag_list_path(tag = nil ) | |
if tag.present? | |
if tag.class == Category | |
return link_to tag, tag_identity_timeline_category_path(tag.parent.parent,tag.parent,tag) | |
end | |
if tag.class == Timeline | |
return link_to tag, tag_identity_timeline_categories_path(tag.parent,tag) | |
end | |
if tag.class == Identity | |
return link_to tag, tag_identity_timelines_path(tag) | |
end | |
end | |
end | |
def find_user(id = nil, email = nil, username = nil) | |
u = (User.where id: id).first if id.present? | |
u = (User.where email: email).first if email.present? | |
u = (User.where username: username).first if username.present? | |
u | |
end | |
def object_summary(obj = nil, column = "", length = 50) | |
summary_fields = [:title ,:summary, :label, :content, :body].collect{|c| c.to_s} | |
if obj.present? | |
obj_class = obj.class | |
if obj_class.respond_to? :columns_hash | |
str_columns = obj_class.columns_hash.collect{|key,value| key if [:text, :string].include? value.type }.compact | |
summary_fields = str_columns & summary_fields | |
end | |
end | |
unless column.present? | |
#column = summary_fields.first | |
column = summary_fields.collect{|f| f if obj.respond_to? f.to_sym}.compact.first | |
end | |
if column.present? and obj.send(column).present? | |
truncate(obj.send(column), :length => length) | |
else | |
"#{obj}" | |
end | |
end | |
def change_ip_to_city(ip=nil) | |
is = IpSearch.new | |
ip ||= "116.228.214.170" | |
is.find_ip_location(ip) | |
#breakpoint | |
#return is.country.gsub("市","") | |
is.country.split("省").last.gsub("市","") | |
end | |
def obj_conditions_params(obj = "Version", hash={}, hash_name = "conditions") | |
# obj = obj.classify.constantize | |
#hash.delete_if {|key, value| !(obj.column_names.include? key.to_s) } | |
{hash_name => hash}.to_param | |
end | |
def obj_params(obj = "Version", hash={}) | |
obj = obj.classify.constantize | |
hash.delete_if {|key, value| !(obj.column_names.include? key.to_s) } | |
hash.to_param | |
end | |
def obj_filter_drop_down_li(obj = "Version", col = '' ,path = nil,count = 20, max_count = 1000) | |
obj_class = obj.classify.constantize | |
if obj_class.column_names.include? col.to_s | |
head = "<ul class='nav nav-pills'> | |
<li class='dropdown'> | |
<a class='dropdown-toggle' data-toggle='dropdown' href='#menu1'>#{obj_class.human_attribute_name(col.gsub("_id",'').to_sym)} | |
<b class='caret'></b> | |
</a> | |
<ul class='dropdown-menu'>" | |
list = obj_class.order("id desc").group(col.to_sym).limit(max_count).uniq.delete_if{|item| item.send(col).nil?}.collect{|item| ["#{item.send((col.gsub("_id",'')))}",item.send(col)]} | |
if col.end_with? "_by" | |
#list = obj.find(:all, :order => "id desc").collect{|v| ["#{(v.send(col.gsub("_id",'').to_sym))}",v.send(col.to_sym)]} | |
#list = obj.select([col.to_sym,:id]).collect{|item| ["#{item.reload.send(col.gsub("_id",''))}",item.send(col)]}.uniq | |
list = obj_class.order("id desc").group(col.to_sym).limit(max_count).uniq.delete_if{|item| item.send(col).nil?}.collect{|item| ["#{item.send(col.gsub("_by",'_user'))}",item.send(col)]}.uniq | |
end | |
path ||= self.send("#{obj.pluralize.downcase}_path") | |
content = list[ 0 .. (count.to_i - 1)].collect{|l| raw "<li>#{link_to l[0],(path +"/?" + obj_conditions_params(obj = obj,{col.to_sym =>l[1]})) }</li>"}.join | |
foot = "</li></ul>" | |
return raw "#{head + content + foot}" | |
end | |
end | |
def mongoid_feild_pluck(obj = "SourceTracker", field = '',opt = {uniq: false}) | |
obj_class = obj.classify.constantize | |
fields = obj_class.fields.collect{|_,v| v.name}.uniq.compact | |
if fields.include? field.to_s | |
set_cache_name = "#{obj_class.name.underscore}_pluck_#{field}" | |
#cache = ActiveSupport::Cache::MemoryStore.new | |
if Rails.cache.read("#{set_cache_name}").nil? | |
result = obj_class.only([field]).map(&field.to_sym) | |
if (uniq = opt.delete(:uniq)).present? | |
result.uniq! | |
end | |
Rails.cache.write("#{set_cache_name}" ,result , :expires_in => 24.hours) | |
end | |
return Rails.cache.read("#{set_cache_name}") | |
end | |
end | |
def mongoid_obj_filter_drop_down_li(obj = "SourceTracker", field = '' ,path = nil,count = 20) | |
obj_class = obj.classify.constantize | |
fields = obj_class.fields.collect{|_,v| v.name}.uniq.compact | |
if fields.include? field.to_s | |
head = "<div class='btn-group'> | |
<button class='btn'>#{obj_class.human_attribute_name(field.to_sym)}</button> | |
<button class='btn dropdown-toggle' data-toggle='dropdown'> | |
<span class='caret'></span> | |
</button> | |
<ul class='dropdown-menu'>" | |
#list = [[human1,real1],[human2,real2]] | |
list = mongoid_feild_pluck(obj = obj_class.name, field = field, {uniq: true} ).compact.collect{|item| [item,item]} | |
if field.to_s.eql? "ip" | |
list = mongoid_feild_pluck(obj = obj_class.name, field = "ip", {uniq: true} ).compact.collect{|item| [change_ip_to_city(ip=item),item]} | |
end | |
path ||= self.send("#{obj.pluralize.downcase}_path") | |
content = list[ 0 .. (count.to_i - 1)].collect{|l| raw "<li>#{link_to l[0],(path +"/?" + obj_conditions_params(obj = obj,{field.to_sym =>l[1]})) }</li>"}.join | |
foot = "</ul></div>" | |
return raw "#{head + content + foot}" | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<%= render 'top_nav_bar', model_class: SourceTracker.new.class%> | |
<%- model_class = SourceTracker.new.class -%> | |
<div class="page-header"> | |
<h1><%=t '.title', :default => model_class.model_name.human.pluralize %></h1> | |
<%= render("common/mod_newest_summary", model_class: model_class) if model_class.present?%> | |
</div> | |
<div class = "source_trackers box"> | |
<table class="table table-striped"> | |
<thead> | |
<tr> | |
<th><%= cache_helper :mongoid_obj_filter_drop_down_li,{:expires_in => 30.minutes},obj = "SourceTracker", field="platform",path= source_trackers_path %></th> | |
<th><%= cache_helper :mongoid_obj_filter_drop_down_li,{},obj = "SourceTracker", field="from",path= source_trackers_path %></th> | |
<th><%= cache_helper :mongoid_obj_filter_drop_down_li,{},obj = "SourceTracker", field="version_number",path= source_trackers_path %></th> | |
<th><%= model_class.human_attribute_name(:ip) %></th> | |
<th><%= cache_helper :mongoid_obj_filter_drop_down_li,{},obj = "SourceTracker", field="ip",path= source_trackers_path %></th> | |
<th><%= model_class.human_attribute_name(:url) %></th> | |
<th><%= model_class.human_attribute_name(:created_at) %></th> | |
<th><%=t '.actions', :default => t("helpers.actions") %></th> | |
</tr> | |
</thead> | |
<tbody> | |
<tbody> | |
<%- indicates = true %> | |
<% @source_trackers.each do |source_tracker| %> | |
<tr> | |
<td><%= source_tracker.platform %></td> | |
<td><%= source_tracker.from %></td> | |
<td><%= source_tracker.version_number %></td> | |
<td><%= source_tracker.ip %></td> | |
<td><%= source_tracker.city %></td> | |
<td><%= source_tracker.url %></td> | |
<td><%= timeago_tag(source_tracker.created_at, :format => :short) if source_tracker.created_at? %></td> | |
<td> | |
<%= link_to t('.show', :default => t("helpers.links.show", :model => model_class.model_name.human)), | |
source_tracker_path(source_tracker), | |
:class => 'btn btn-mini' | |
%> | |
<%= link_to t('.destroy', :default => t("helpers.links.destroy", :model => model_class.model_name.human)), | |
source_tracker_path(source_tracker), | |
:method => :delete, | |
:confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')), | |
:class => 'btn btn-mini btn-danger' %> | |
</td> | |
</tr> | |
<% end %> | |
</tbody> | |
</table> | |
<%= will_paginate @source_trackers %> | |
<i><%= "本次检索: #{@source_trackers.total_entries}"%></i> | |
<br /> | |
<%# form_tag(query_source_tracker_path, :method => :put) do |f| %> | |
<%= link_to '测试', new_source_tracker_path(source_tracker: {platform: "email", from: "bbtang", version_number: "week1"}) %> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
class ProfilesController < ApplicationController | |
load_and_authorize_resource | |
caches_action :index, :feed, expires_in: 10.minutes, cache_path: Proc.new { |controller| current_user.present? ? controller.params.merge(user_id: current_user.id) : controller.params } | |
caches_action :show, :public, expires_in: 1.hours, cache_path: Proc.new { |controller| current_user.present? ? controller.params.merge(user_id: current_user.id) : controller.params } | |
cache_sweeper :resource_sweeper | |
Model_class = Profile.new.class | |
# GET /profiles | |
# GET /profiles.json | |
def index | |
if params[:conditions].present? | |
@profiles = Profile.where(params[:conditions]).paginate(:page => params[:page]).order('id DESC') | |
else | |
@profiles = Profile.paginate(:page => params[:page]).order('id DESC') | |
end | |
breadcrumbs.add I18n.t("helpers.titles.#{current_action}", :model => Model_class.model_name.human), profiles_path | |
#fresh_when :etag => [Model_class.last] # should without respond_to | |
# also can use stale? | |
if stale? :etag => [Model_class.last] | |
respond_to do |format| | |
format.html # index.html.erb | |
format.json { render json: @profiles } | |
end | |
end | |
end | |
# GET /profiles/1 | |
# GET /profiles/1.json | |
def show | |
@profile = Profile.find(params[:id]) | |
breadcrumbs.add I18n.t("helpers.titles.#{current_action}", :model => Model_class.model_name.human), profile_path(@profile) | |
if stale? :etag => [@profile] | |
respond_to do |format| | |
format.html # show.html.erb | |
format.json { render json: @profile } | |
end | |
end | |
end | |
# GET /profiles/new | |
# GET /profiles/new.json | |
def new | |
ip = request.env["REMOTE_ADDR"] if not request.env["REMOTE_ADDR"]=='127.0.0.1' | |
@contry = change_ip_to_city(ip) | |
@profile = Profile.new | |
set_instace_var | |
respond_to do |format| | |
format.html # new.html.erb | |
format.json { render json: @profile } | |
end | |
end | |
# GET /profiles/1/edit | |
def edit | |
ip = request.env["REMOTE_ADDR"] if not request.env["REMOTE_ADDR"] == '127.0.0.1' | |
@contry = change_ip_to_city(ip) | |
@profile = Profile.find(params[:id]) | |
set_instace_var | |
breadcrumbs.add I18n.t("helpers.titles.#{current_action}", :model => Model_class.model_name.human), edit_profile_path(@profile) | |
end | |
# POST /profiles | |
# POST /profiles.json | |
def create | |
@profile = Profile.new(params[:profile]) | |
respond_to do |format| | |
if @profile.save | |
format.html { redirect_to @profile, notice: 'Profile was successfully created.' } | |
format.json { render json: @profile, status: :created, location: @profile } | |
else | |
format.html { render action: "new" } | |
format.json { render json: @profile.errors, status: :unprocessable_entity } | |
end | |
end | |
end | |
# PUT /profiles/1 | |
# PUT /profiles/1.json | |
def update | |
@profile = Profile.find(params[:id]) | |
respond_to do |format| | |
if @profile.update_attributes(params[:profile]) | |
format.html { redirect_to @profile, notice: 'Profile was successfully updated.' } | |
format.json { head :no_content } | |
else | |
format.html { render action: "edit" } | |
format.json { render json: @profile.errors, status: :unprocessable_entity } | |
end | |
end | |
end | |
# DELETE /profiles/1 | |
# DELETE /profiles/1.json | |
def destroy | |
@profile = Profile.find(params[:id]) | |
@profile.destroy | |
respond_to do |format| | |
format.html { redirect_to profiles_url } | |
format.json { head :no_content } | |
end | |
end | |
protected | |
def set_instace_var | |
if self.instance_variable_defined? "@profile" | |
(3 - @profile.babies.length).times { @profile.babies.new } | |
end | |
end | |
def change_ip_to_city (ip=nil) | |
is = IpSearch.new | |
ip ||= "116.228.214.170" | |
is.find_ip_location(ip) | |
#breakpoint | |
return is.country[0].gsub("市","") | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
##CacheableCSRFToken allows you to easily cache Ruby on Rails pages or partials containing a CSRF protection token. The user-specific token will inserted in the HTML before the response is sent to the user. | |
# gem "cacheable-csrf-token-rails", "~> 0.1.0" # but it only work on rails (>= 3.2.5) | |
#http://rails-everyday.group.iteye.com/group/wiki/1160 | |
#http://cobaltedge.com/rails-action-caching-with-query-parameters | |
class ResourceSweeper < ActionController::Caching::Sweeper | |
#observe Knowledge # This sweeper is going to keep an eye on the Knowledge model | |
observe Setting.observe_models.split(" ").collect{|object| object.constantize if object.class_exists?}.compact.uniq | |
# If our sweeper detects that a Knowledge was created call this | |
def after_create(resource) | |
expire_cache_for(resource) | |
end | |
# If our sweeper detects that a Knowledge was updated call this | |
# http://stackoverflow.com/questions/6367396/filtering-sweeper-calls-in-rails | |
=begin | |
The current_sign_in_at and last_sign_in_at are the two fields that are updated by devise during sign_in and sign_out. This code makes the obvious assumption that you have no application logic of your own to update these fields and only devise updates them. | |
=end | |
# but not work for me so skip User model | |
def after_update(resource) | |
#expire_cache_for(resource) | |
unless resource.is_a? User and (resource.current_sign_in_at_changed? or resource.last_sign_in_at_changed?) | |
expire_cache_for(resource) | |
end | |
end | |
# If our sweeper detects that a Knowledge was deleted call this | |
def after_destroy(resource) | |
expire_cache_for(resource) | |
end | |
=begin | |
def after_save(resource) | |
item = resource.is_a?(List) ? resource : resource.class | |
resource_name = resource.class.name.underscore.pluralize | |
expire_page(:controller => resource_name, :action => %w( show public feed ), :id => item.id) | |
expire_action(:controller => resource_name, :action => "all") | |
item.shares.each { |share| expire_page(:controller => resource_name, :action => "show", :id => share.url_key) } | |
end | |
=end | |
private | |
def expire_cache_for(resource) | |
resource_name = resource.class.name.underscore.pluralize | |
controller_name = is_namespace_resources(resource.class) ? "/#{resource_name}" : resource_name | |
# Expire the index page now that we added a new resource | |
#expire_page(:controller => resource_name, :action => 'index') | |
actions = %w( index show public feed ).collect{|action| action if route_checker?(controller_name,action)}.compact | |
expire_page(:controller => controller_name, :action => actions, :id => resource.id) | |
expire_action(:controller => controller_name, :action => actions) | |
#%r{pages/\d*/notes} | |
#ActionController::Caching::Actions::ActionCachePath.new(self, {:controller => controller_name, :action => "index"}, false).path | |
#"localhost:3000/knowledges" | |
# bellow will expire action no matter controller.params | |
actions.each do |action| | |
if route_checker?(controller_name,action) | |
action_cache_path = ActionController::Caching::Actions::ActionCachePath.new(self, {:controller => controller_name, :action => action}, false).path | |
expire_action(%r{#{action_cache_path}} ) | |
end | |
end | |
# Expire a fragment | |
#expire_fragment('all_available_'<< resource_name) | |
end | |
def namespace_resources | |
[ "User","Version","Quiz", | |
"QuizCollection","CmsRole", | |
"Category","Identity","Timeline" ] | |
end | |
def is_namespace_resources(resource_name) | |
namespace_resources.include?(resource_name) | |
end | |
def get_id(resource) | |
#resource.is_a?(User) ? resource.id : resource.user_id | |
end | |
def get_observe_models | |
observe_models = Setting.observe_models.split(" ") | |
observe_models ||= ["Knowledge", "Note", "News", "Profile", "Question", "Quiz", "QuizCollection", "Subject", "User", "Answer", "Attachment", "CmsRole"] | |
observe_models.collect{|object| object.constantize if object.class_exists?}.compact.uniq | |
end | |
def route_checker(controller,action,opt={}) | |
url_for({:controller => controller, :action => action}.merge opt).present? ? url_for({:controller => controller, :action => action}.merge opt) : false rescue false | |
end | |
def route_checker?(controller,action,opt={}) | |
route_checker(controller,action,opt) ? true : false rescue false | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment