Class: Workarea::Cache::Varies

Inherits:
Object
  • Object
show all
Defined in:
lib/workarea/cache.rb

Defined Under Namespace

Classes: UnsupportedSessionAccess

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, varies = Workarea.config.cache_varies) ⇒ Varies

Returns a new instance of Varies.



69
70
71
72
# File 'lib/workarea/cache.rb', line 69

def initialize(env, varies = Workarea.config.cache_varies)
  @env = env
  @varies = Array.wrap(varies)
end

Instance Attribute Details

#envObject (readonly)

Returns the value of attribute env.



12
13
14
# File 'lib/workarea/cache.rb', line 12

def env
  @env
end

Class Method Details

.on(&block) ⇒ Object

This allows varying the HTTP and fragment caching on cookies, session or other request-based info (like headers). This is useful when you’d like to vary responses based on some data the browser won’t be sending - like what segments a request will be in or geolocation. You’ll want to be VERY careful when doing this - remember this block will be run on every request, so doing expensive things like DB queries is discouraged.

The source of data on which you can vary is an ActionDispatch::Request: api.rubyonrails.org/classes/ActionDispatch/Request.html

This allows you to access headers, session, cookies, IP address, etc. Within this block, all missing method calls are delegated to an instance of ActionDispatch::Request. You also have access to an instance of Workarea::Geolocation to work with as well (available by calling geolocation).

Here are some examples of how you might use this varying:

Retailer wants separate content for each region:

Workarea::Cache::Varies.on { geolocation.region }

Some users have custom price lists:

# in app/controllers/workarea/application_controller.decorator
after_action :set_price_list

def set_price_list
  session[:price_list_id] = current_user.try(:price_list_id)
end

# in config/initializers/workarea.rb
Workarea::Cache::Varies.on { session[:price_list_id] }

A segmentation plugin sets segments based on the current user:

# in app/controllers/workarea/application_controller.decorator
after_action :set_segment_ids

def set_segment_ids
  session[:segment_ids] = Segments.find_matching(current_user).map(&:id)
end

# in config/initializers/workarea.rb
Workarea::Cache::Varies.on { session[:segment_ids].sort.join }


64
65
66
67
# File 'lib/workarea/cache.rb', line 64

def self.on(&block)
  Workarea.config.cache_varies ||= []
  Workarea.config.cache_varies << block
end

Instance Method Details

#cookiesObject



78
79
80
# File 'lib/workarea/cache.rb', line 78

def cookies
  request.cookie_jar
end

#geolocationObject



91
92
93
# File 'lib/workarea/cache.rb', line 91

def geolocation
  @geolocation ||= Workarea::Geolocation.new(env, request.remote_ip)
end

#requestObject



87
88
89
# File 'lib/workarea/cache.rb', line 87

def request
  @request ||= ActionDispatch::Request.new(env)
end

#sessionObject



82
83
84
85
# File 'lib/workarea/cache.rb', line 82

def session
  raise UnsupportedSessionAccess unless session_cookie_store?
  @session ||= (cookies.signed_or_encrypted[session_key] || {}).with_indifferent_access
end

#to_sObject



74
75
76
# File 'lib/workarea/cache.rb', line 74

def to_s
  @to_s ||= @varies.map { |v| instance_exec(&v).to_s }.join(':')
end