rooftop-rails 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ce7b53b614dba3b91d76917209fdd360b3074ee
4
- data.tar.gz: 9b3034dca31a3d7011d635b46639e519ebb90a51
3
+ metadata.gz: 44f03f4480ef66da90df9283ee01437c7e24fb1f
4
+ data.tar.gz: 5d5bcfd4bbe1fc4d4d73ca638226bd35c04da30e
5
5
  SHA512:
6
- metadata.gz: 7420b709d0dd54f2e485a87240a50e319806df71870d730d022d71529bf4a09407d1674fee1a29c2eb68b8cdea539d9e24c6451848533096f8d68d9985624f8e
7
- data.tar.gz: dc72a561f64cb5e2ab552771ca5bfe61cba476117d9a39be140090cf44fb29db9b2eac4794d5750c71f12e431e7644f33037f28769a4e09f5d22fcaa4416a8e4
6
+ metadata.gz: 45f27bfd588ba45324abae25ee6d798faaf78a74f91237009ee838d9a2275ff37fbb4f123476d09adbe3c1e8cb7a920d407da8572d27183866995b0c15e12afc
7
+ data.tar.gz: a1263337fc73348789ed7f3ea001532ca0556ba706a22326f87f46f5bd03d62ff23f6daa0e90e9df312fc416a7bd5797de9474f5a6cbe0a9376882d8fda86b61
@@ -13,7 +13,7 @@ module Rooftop
13
13
  # By adding a call to `nested_rooftop_resource` in your controller class, the following happens:
14
14
  # - The resource model you identify has Rooftop::Rails::NestedModel mixed into it
15
15
  # - Methods for finding a model object and validating that the path is correct are added
16
- # For example:
16
+ # @example
17
17
  # class PagesController
18
18
  # include Rooftop::Rails::NestedResource
19
19
  # nested_rooftop_resource :page
@@ -0,0 +1,38 @@
1
+ class Rooftop::Rails::WebhooksController < ActionController::Base
2
+ # if Rooftop::Rails.configuration.authenticate_webhooks
3
+ # http_basic_authenticate_with name: Rooftop::Rails.configuration.webhooks_username,
4
+ # password: Rooftop::Rails.configuration.webhooks_password
5
+ # end
6
+
7
+ skip_before_filter :verify_authenticity_token, :only => [:create]
8
+
9
+ #this is where we receive a webhook, via a POST
10
+ def create
11
+ # Rooftop will POST data to this endpoint, and we can decide what to do with it.
12
+ # The data included in the POST is as follows:
13
+
14
+ request.format = :json
15
+ update_type = params[:status]
16
+
17
+ # All we do here is publish an ActiveSupport::Notification, which is subscribed to
18
+ # elsewhere. In this gem are subscription options for timestamp or object caching,
19
+ # implement your own and subscribe in an initializer.
20
+ ActiveSupport::Notifications.instrument("rooftop.#{update_type}", params)
21
+
22
+ #must return an ok
23
+ render nothing: true
24
+ end
25
+
26
+ def debug
27
+ render text: "Debug method works ok"
28
+ end
29
+
30
+ private
31
+
32
+ def webhook_params
33
+ params.permit!
34
+ end
35
+
36
+
37
+
38
+ end
@@ -0,0 +1,30 @@
1
+ module Rooftop
2
+ module Rails
3
+ module MenuHelper
4
+
5
+ # Given a Rooftop::Menus::Item, return a path for it, or nil if we can't.
6
+ def path_for_menu_item(item)
7
+ begin
8
+ # for links elsewhere, return the url as-is
9
+ if item.object_type == "custom"
10
+ return item.url
11
+ end
12
+
13
+ # otherwise we need to determine if we have a nested resource
14
+ if item.object_ancestor_slugs.present?
15
+ # we have a nested tree of slugs
16
+ resource_id = item.object_ancestor_slugs.split(",").push(item.object_slug).join("/")
17
+ else
18
+ resource_id = item.object_slug
19
+ end
20
+
21
+ return Rooftop::Rails::RouteResolver.new(item.object_type, resource_id).resolve
22
+ rescue
23
+ nil
24
+ end
25
+ end
26
+
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,96 @@
1
+ module Rooftop
2
+ module Rails
3
+ # This mixin adds object caching when you call find(). It overloads the find() method to cache the result, and read that instead if possible.
4
+ module ObjectCache
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ # Utility method to get the cache key for the instance.
10
+ def cache_key
11
+ "#{self.class.cache_key_base}/#{self.id}"
12
+ end
13
+
14
+ module ClassMethods
15
+
16
+ # Base of the cache key for this class.
17
+ def cache_key_base
18
+ "rooftop/#{self.to_s.underscore}"
19
+ end
20
+
21
+ # Redeclare the find() method, with caching. Only pass uncached keys to the super method.
22
+ def find(*ids)
23
+ if Rooftop::Rails.configuration.perform_object_caching
24
+ ids.uniq!
25
+ uncached_ids = ids.reject {|i| ::Rails.cache.read("#{cache_key_base}/#{i}").present?}
26
+ [super(*uncached_ids)].flatten.reject(&:blank?).collect do |object|
27
+ ::Rails.logger.debug("Caching #{cache_key_base}/#{object.id}")
28
+ ::Rails.cache.write(object.cache_key,object)
29
+ end
30
+ all_objects = ids.collect do |id|
31
+ ::Rails.cache.read("#{cache_key_base}/#{id}")
32
+ end
33
+
34
+ all_objects.length == 1 ? all_objects.first : all_objects
35
+ else
36
+ super
37
+ end
38
+ end
39
+
40
+ def where(args)
41
+ #Sort the arguments, and any keys which are arrays
42
+ args = Hash[args.sort.each {|k,v| v.sort! if v.is_a?(Array)}]
43
+ # Generate a hash for keying the cache of the results
44
+ args_hash = Digest::MD5.hexdigest(args.to_s)
45
+ cache_key = "#{cache_key_base}/collection_query/#{args_hash}"
46
+ # first see if we have a collection which matches the args
47
+ cached_collection = ::Rails.cache.read(cache_key)
48
+ # if it's present, then we can return it directly.
49
+ if cached_collection.present?
50
+ return cached_collection
51
+ else
52
+ # If not, then we need to call super() to get it from the API
53
+ collection = super(args)
54
+ # and write it into the cache
55
+ ::Rails.cache.write(cache_key,collection)
56
+ # We also iterate over the collection and cache each object, and cache the argument hash against each object
57
+ collection.each do |object|
58
+ # This is a bit funky and circular. We store an array of hashes for queries to which this object belongs.
59
+ # If the object cache needs to be removed, we can iterate through those hashes and clear the collection caches too.
60
+ collection_query_hash_key = "#{object.cache_key}/collection_hashes"
61
+ collection_hashes = ::Rails.cache.read(collection_query_hash_key) || []
62
+ collection_hashes << args_hash
63
+ ::Rails.cache.write(collection_query_hash_key, collection_hashes)
64
+ # this is the object cache - i.e. it'll respond with a cache lookup for Page.find(14) or whatever
65
+ ::Rails.cache.write(object.cache_key,object)
66
+ end
67
+ collection
68
+ end
69
+ end
70
+
71
+ # A method to expire the relevant caches for a collection of objects or ids
72
+ # @param args [Array] of either objects which respond to `.id`, or ids themselves
73
+ def expire_cache_for(*args)
74
+ args = args.collect {|a| a.respond_to?(:id) ? a.id : a}
75
+ # the caches we need to clear are:
76
+ # - the object cache
77
+ # - any collection caches which included this object
78
+ args.each do |id|
79
+ object_cache_key = "#{cache_key_base}/#{id}"
80
+ collection_keys = (::Rails.cache.read("#{object_cache_key}/collection_hashes") || []).collect do |hash|
81
+ "#{cache_key_base}/collection_query/#{hash}"
82
+ end
83
+ collection_keys << "#{object_cache_key}/collection_hashes"
84
+ [collection_keys + [object_cache_key]].flatten.each do |key|
85
+ ::Rails.cache.delete(key)
86
+ end
87
+
88
+ end
89
+
90
+
91
+ end
92
+
93
+ end
94
+ end
95
+ end
96
+ end
data/config/routes.rb CHANGED
@@ -1,4 +1,4 @@
1
- Rails.application.routes.draw do
1
+ Rooftop::Rails::Engine.routes.draw do
2
2
  resources :webhooks, only: [:create], defaults: { format: :json } do
3
3
  collection do
4
4
  scope constraints: Rooftop::Rails::DevelopmentConstraint do
data/lib/rooftop/rails.rb CHANGED
@@ -27,7 +27,8 @@ module Rooftop
27
27
  :preview_password,
28
28
  :preview_domain,
29
29
  :enable_preview_domain,
30
- :perform_caching,
30
+ :perform_http_response_caching,
31
+ :perform_object_caching,
31
32
  :cache_store,
32
33
  :cache_logger,
33
34
  :ssl_options,
@@ -36,7 +37,8 @@ module Rooftop
36
37
 
37
38
  def initialize
38
39
  @authenticate_webhooks = true
39
- @perform_caching = ::Rails.configuration.action_controller.perform_caching
40
+ @perform_http_response_caching = ::Rails.configuration.action_controller.perform_caching
41
+ @perform_object_caching = ::Rails.configuration.action_controller.perform_caching
40
42
  @cache_store = ::Rails.cache
41
43
  @cache_logger = ::Rails.logger
42
44
  @ssl_options = {}
@@ -18,7 +18,7 @@ module Rooftop
18
18
  config.advanced_options = Rooftop::Rails.configuration.advanced_options
19
19
  config.api_path = Rooftop::Rails.configuration.api_path
20
20
  config.url = Rooftop::Rails.configuration.url || "https://#{config.site_name}.rooftopcms.io"
21
- config.perform_caching = Rooftop::Rails.configuration.perform_caching
21
+ config.perform_caching = Rooftop::Rails.configuration.perform_http_response_caching
22
22
  config.cache_store = Rooftop::Rails.configuration.cache_store
23
23
  config.cache_logger = Rooftop::Rails.configuration.cache_logger
24
24
  config.ssl_options = Rooftop::Rails.configuration.ssl_options
@@ -35,6 +35,26 @@ module Rooftop
35
35
  initializer "add_helpers" do
36
36
  ActiveSupport.on_load(:action_view) do
37
37
  include Rooftop::Rails::ContentHelper
38
+ include Rooftop::Rails::MenuHelper
39
+ end
40
+ end
41
+
42
+ initializer "add_caching_to_rooftop_models" do
43
+ ::Rails.application.eager_load!
44
+ Rooftop::Base.included_classes.each do |klass|
45
+ klass.send(:include, Rooftop::Rails::ObjectCache)
46
+ end
47
+ end
48
+
49
+ initializer "clear_caches_on_webhook_notification" do
50
+ ActiveSupport::Notifications.subscribe(/rooftop.*/) do |name, start, finish, id, payload|
51
+ content_type = payload[:type]
52
+ if Rooftop.configuration.post_type_mapping[content_type].present?
53
+ klass = Rooftop.configuration.post_type_mapping[content_type]
54
+ else
55
+ klass = content_type.classify.constantize
56
+ end
57
+ klass.send(:expire_cache_for, payload[:id])
38
58
  end
39
59
  end
40
60
  end
@@ -1,5 +1,5 @@
1
1
  module Rooftop
2
2
  module Rails
3
- VERSION = "0.0.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rooftop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Error Studio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-09 00:00:00.000000000 Z
11
+ date: 2015-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: require_all
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 0.0.5
61
+ version: 0.0.6
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: 0.0.5
68
+ version: 0.0.6
69
69
  description: This gem provides utility methods and a mountable engine for Rails applications
70
70
  using the Rooftop gem
71
71
  email:
@@ -76,10 +76,11 @@ extra_rdoc_files: []
76
76
  files:
77
77
  - Rakefile
78
78
  - app/controllers/concerns/rooftop/rails/nested_resource.rb
79
- - app/controllers/rooftop_rails/webhooks_controller.rb
79
+ - app/controllers/rooftop/rails/webhooks_controller.rb
80
80
  - app/helpers/rooftop/rails/content_helper.rb
81
- - app/helpers/rooftop/webhooks_helper.rb
81
+ - app/helpers/rooftop/rails/menu_helper.rb
82
82
  - app/models/concerns/rooftop/rails/nested_model.rb
83
+ - app/models/concerns/rooftop/rails/object_cache.rb
83
84
  - config/routes.rb
84
85
  - lib/rooftop/rails.rb
85
86
  - lib/rooftop/rails/development_constraint.rb
@@ -1,5 +0,0 @@
1
- class Rooftop::Rails::WebhooksController < ::ApplicationController
2
- def create
3
- return render text: "CREATE"
4
- end
5
- end
@@ -1,2 +0,0 @@
1
- module Rooftop::Rails::WebhooksHelper
2
- end