Module: Merb::Cache::Controller::InstanceMethods

Defined in:
lib/merb-cache/merb_ext/controller/instance_methods.rb

Instance Method Summary collapse

Instance Method Details

#_cache_after(conditions = {}) ⇒ Object



67
68
69
70
71
72
73
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 67

def _cache_after(conditions = {})
  if @_cached == false
    if Merb::Cache[_lookup_store(conditions)].write(self, nil, *_parameters_and_conditions(conditions))
      @_cache_write = true
    end
  end
end

#_cache_before(conditions = {}) ⇒ Object



56
57
58
59
60
61
62
63
64
65
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 56

def _cache_before(conditions = {})
  unless @_force_cache
    if @_skip_cache.nil? && data = Merb::Cache[_lookup_store(conditions)].read(self, _parameters_and_conditions(conditions).first)
      throw(:halt, data)
      @_cached = true
    else
      @_cached = false
    end
  end
end

#_eager_cache_after(klass, action, options = {}, blk = nil) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 75

def _eager_cache_after(klass, action, options = {}, blk = nil)
  unless @skip_cache
    run_later do
      env = request.env.dup
      env.merge!(options.only(:method, :uri))

      controller = klass.eager_dispatch(action, request.params.dup, env, blk)
      conditions = self.class._cache[action]
      
      Merb::Cache[controller._lookup_store(conditions)].write(controller, nil, *controller._parameters_and_conditions(conditions))
    end
  end
end

#_lookup_store(conditions = {}) ⇒ Object



126
127
128
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 126

def _lookup_store(conditions = {})
  conditions[:store] || conditions[:stores] || default_cache_store
end

#_parameters_and_conditions(conditions) ⇒ Object

ugly, please make me purdy’er



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 136

def _parameters_and_conditions(conditions)
  parameters = {}

  if self.class.respond_to? :action_argument_list
    arguments, defaults = self.class.action_argument_list[action_name]
    arguments.inject(parameters) do |parameters, arg|
      if defaults.include?(arg.first)
        parameters[arg.first] = self.params[arg.first] || arg.last
      else
        parameters[arg.first] = self.params[arg.first]
      end
      parameters
    end
  end

  case conditions[:params]
  when Symbol
    parameters[conditions[:params]] = self.params[conditions[:params]]
  when Array
    conditions[:params].each do |param|
      parameters[param] = self.params[param]
    end
  end

  return parameters, conditions.except(:params, :store, :stores, :method, :uri)
end

#default_cache_storeObject

Overwrite this in your controller to change the default store for a given controller



131
132
133
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 131

def default_cache_store
  Merb::Cache.default_store_name
end

#eager_cache(action, options = {}, env = request.env.dup, &blk) ⇒ Object

Note:

There are a number of options specific to eager_cache in the conditions hash

- :uri the uri of the resource you want to eager cache (needed by the page store but can be provided instead by a block)
- :method http method used (defaults to :get)
- :params hash of params to use when sending the request to cache

After the request has finished, cache the action without holding some poor user up generating the cache (through run_later)

Examples:

eager_cache :index, :uri => ‘/articles’ # When the update action is completed, a get request to :index with ‘/articles’ uri will be cached (if you use the page store, this will be stored in ‘/articles.html’)

eager_cache :index # Same after the create action but since no uri is given, the current uri is used with the default http method (:get). Useful default for resource controllers

eager_cache([Timeline, :index]) :uri => url(:timelines)}}

Parameters:

  • action (Array[Controller,Symbol], Symbol)

    the target option to cache (if no controller is given, the current controller is used)

  • options (Hash) (defaults to: {})

    Request options. See note for details

  • env (Hash) (defaults to: request.env.dup)

    request environment variables

  • blk (Block)

    Block run to generate the request or controller used for eager caching after trigger_action has run



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 107

def eager_cache(action, options = {}, env = request.env.dup, &blk)
  unless @_skip_cache
    if action.is_a?(Array)
      klass, action = *action
    else
      klass = self.class
    end

    run_later do
      env = request.env.dup
      env.merge!(options.only(:method, :uri, :params))
      controller = klass.eager_dispatch(action, {}, env, blk)
    end
  end
end

#fetch_fragment(opts = {}, conditions = {}, &proc) ⇒ Object

Used to cache the result of a long running block

Examples:

fetch_fragment { #stuff to do}



45
46
47
48
49
50
51
52
53
54
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 45

def fetch_fragment(opts = {}, conditions = {}, &proc)
  if opts[:cache_key].blank?
    file, line = proc.to_s.scan(%r{^#<Proc:0x\w+@(.+):(\d+)>$}).first
    fragment_key = "#{file}[#{line}]"
  else
    fragment_key = opts.delete(:cache_key)
  end
  
  concat(Merb::Cache[_lookup_store(conditions)].fetch(fragment_key, opts, conditions) { capture(&proc) }, proc.binding)
end

#fetch_partial(template, opts = {}, conditions = {}) ⇒ Object

Note:

The opts hash supports :params_for_cache which can be used to specify which parameters will be passed to the store. If you call ‘fetch_partial` with parameters that are instance of model it will fail, so you need to use :params_for_cache in this case

Partial / fragment caches are written / retrieved using fetch_partial

Examples:

fetch_partial :bar

fetch_partial :foo, :with => @foo, :params_for_cache => => @foo.id

fetch_partial :store, :with => @items, :params_for_cache => => @store.version, :store_id => @store.id



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 16

def fetch_partial(template, opts={}, conditions = {})
  template_id = template.to_s
  if template_id =~ %r{^/}
    template_path = File.dirname(template_id) / "_#{File.basename(template_id)}"
  else
    kontroller = (m = template_id.match(/.*(?=\/)/)) ? m[0] : controller_name
    template_id = "_#{File.basename(template_id)}"
  end

  unused, template_key = _template_for(template_id, opts.delete(:format) || content_type, kontroller, template_path)
  template_key.gsub!(File.expand_path(Merb.root),'')

  fetch_proc = lambda { partial(template, opts) }
  params_for_cache = opts.delete(:params_for_cache) || opts.dup

  concat(Merb::Cache[_lookup_store(conditions)].fetch(template_key, params_for_cache, conditions, &fetch_proc), fetch_proc.binding)
end

#force_cache!Object



124
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 124

def force_cache!; @_force_cache = true; end

#skip_cache!Object



123
# File 'lib/merb-cache/merb_ext/controller/instance_methods.rb', line 123

def skip_cache!; @_skip_cache = true; end