Skip to content

Instantly share code, notes, and snippets.

@jhjguxin
Last active October 13, 2015 22:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhjguxin/4265619 to your computer and use it in GitHub Desktop.
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 ...
<% 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 %>
# 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
# 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
# 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
<%= 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>
# 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
# 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