render_sync 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +153 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +521 -0
- data/Rakefile +9 -0
- data/app/assets/javascripts/sync.coffee +355 -0
- data/app/controllers/sync/refetches_controller.rb +56 -0
- data/app/helpers/render_sync/config_helper.rb +15 -0
- data/config/routes.rb +3 -0
- data/config/sync.yml +21 -0
- data/lib/generators/render_sync/install_generator.rb +14 -0
- data/lib/generators/render_sync/templates/sync.ru +14 -0
- data/lib/generators/render_sync/templates/sync.yml +34 -0
- data/lib/render_sync.rb +174 -0
- data/lib/render_sync/action.rb +39 -0
- data/lib/render_sync/actions.rb +114 -0
- data/lib/render_sync/channel.rb +23 -0
- data/lib/render_sync/clients/dummy.rb +22 -0
- data/lib/render_sync/clients/faye.rb +104 -0
- data/lib/render_sync/clients/pusher.rb +77 -0
- data/lib/render_sync/controller_helpers.rb +33 -0
- data/lib/render_sync/engine.rb +24 -0
- data/lib/render_sync/erb_tracker.rb +49 -0
- data/lib/render_sync/faye_extension.rb +45 -0
- data/lib/render_sync/model.rb +174 -0
- data/lib/render_sync/model_actions.rb +60 -0
- data/lib/render_sync/model_change_tracking.rb +97 -0
- data/lib/render_sync/model_syncing.rb +65 -0
- data/lib/render_sync/model_touching.rb +35 -0
- data/lib/render_sync/partial.rb +112 -0
- data/lib/render_sync/partial_creator.rb +47 -0
- data/lib/render_sync/reactor.rb +48 -0
- data/lib/render_sync/refetch_model.rb +21 -0
- data/lib/render_sync/refetch_partial.rb +43 -0
- data/lib/render_sync/refetch_partial_creator.rb +21 -0
- data/lib/render_sync/renderer.rb +19 -0
- data/lib/render_sync/resource.rb +115 -0
- data/lib/render_sync/scope.rb +113 -0
- data/lib/render_sync/scope_definition.rb +30 -0
- data/lib/render_sync/view_helpers.rb +106 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/sync/users/_show.html.erb +1 -0
- data/test/dummy/app/views/sync/users/refetch/_show.html.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +22 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +8 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/log/test.log +626 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/em_minitest_spec.rb +100 -0
- data/test/fixtures/sync_auth_token_missing.yml +6 -0
- data/test/fixtures/sync_erb.yml +7 -0
- data/test/fixtures/sync_faye.yml +7 -0
- data/test/fixtures/sync_pusher.yml +8 -0
- data/test/models/group.rb +3 -0
- data/test/models/project.rb +2 -0
- data/test/models/todo.rb +8 -0
- data/test/models/user.rb +82 -0
- data/test/sync/abstract_controller.rb +3 -0
- data/test/sync/action_test.rb +82 -0
- data/test/sync/channel_test.rb +15 -0
- data/test/sync/config_test.rb +25 -0
- data/test/sync/erb_tracker_test.rb +72 -0
- data/test/sync/faye_extension_test.rb +87 -0
- data/test/sync/message_test.rb +159 -0
- data/test/sync/model_test.rb +315 -0
- data/test/sync/partial_creator_test.rb +35 -0
- data/test/sync/partial_test.rb +107 -0
- data/test/sync/protected_attributes_test.rb +39 -0
- data/test/sync/reactor_test.rb +18 -0
- data/test/sync/refetch_model_test.rb +26 -0
- data/test/sync/refetch_partial_creator_test.rb +16 -0
- data/test/sync/refetch_partial_test.rb +74 -0
- data/test/sync/renderer_test.rb +19 -0
- data/test/sync/resource_test.rb +181 -0
- data/test/sync/scope_definition_test.rb +39 -0
- data/test/sync/scope_test.rb +113 -0
- data/test/test_helper.rb +66 -0
- data/test/travis/sync.ru +14 -0
- data/test/travis/sync.yml +21 -0
- metadata +317 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
module RenderSync
|
2
|
+
module Clients
|
3
|
+
class Pusher
|
4
|
+
|
5
|
+
def setup
|
6
|
+
require 'pusher'
|
7
|
+
::Pusher.app_id = RenderSync.app_id
|
8
|
+
::Pusher.key = RenderSync.api_key
|
9
|
+
::Pusher.secret = RenderSync.auth_token
|
10
|
+
|
11
|
+
if RenderSync.pusher_api_scheme
|
12
|
+
::Pusher.scheme = RenderSync.pusher_api_scheme
|
13
|
+
end
|
14
|
+
|
15
|
+
if RenderSync.pusher_api_host
|
16
|
+
::Pusher.host = RenderSync.pusher_api_host
|
17
|
+
end
|
18
|
+
|
19
|
+
if RenderSync.pusher_api_port
|
20
|
+
::Pusher.port = RenderSync.pusher_api_port
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def batch_publish(*args)
|
25
|
+
Message.batch_publish(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_message(*args)
|
29
|
+
Message.new(*args)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Public: Normalize channel to adapter supported format
|
33
|
+
#
|
34
|
+
# channel - The string channel name
|
35
|
+
#
|
36
|
+
# Returns The normalized channel prefixed with supported format for Pusher
|
37
|
+
def normalize_channel(channel)
|
38
|
+
channel
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
class Message
|
43
|
+
|
44
|
+
attr_accessor :channel, :data
|
45
|
+
|
46
|
+
def self.batch_publish(messages)
|
47
|
+
messages.each do |message|
|
48
|
+
message.publish
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize(channel, data)
|
53
|
+
self.channel = channel
|
54
|
+
self.data = data
|
55
|
+
end
|
56
|
+
|
57
|
+
def publish
|
58
|
+
if RenderSync.async?
|
59
|
+
publish_asynchronous
|
60
|
+
else
|
61
|
+
publish_synchronous
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def publish_synchronous
|
66
|
+
::Pusher.trigger([channel], 'sync', data)
|
67
|
+
end
|
68
|
+
|
69
|
+
def publish_asynchronous
|
70
|
+
RenderSync.reactor.perform do
|
71
|
+
::Pusher.trigger_async([channel], 'sync', data)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RenderSync
|
2
|
+
|
3
|
+
module ControllerHelpers
|
4
|
+
|
5
|
+
include Actions
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def enable_sync(options = {})
|
13
|
+
around_filter :enable_sync, options
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def enable_sync
|
21
|
+
RenderSync::Model.enable(sync_render_context) do
|
22
|
+
yield
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# ControllerHelpers overrides Action#sync_render_context to use self as
|
27
|
+
# context to allow full access to request/response cycle
|
28
|
+
# over default abstract Renderer class
|
29
|
+
def sync_render_context
|
30
|
+
self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RenderSync
|
2
|
+
|
3
|
+
class Engine < Rails::Engine
|
4
|
+
# Loads the sync.yml file if it exists.
|
5
|
+
initializer "sync.config", group: :all do
|
6
|
+
path = Rails.root.join("config/sync.yml")
|
7
|
+
RenderSync.load_config(path, Rails.env) if path.exist?
|
8
|
+
end
|
9
|
+
|
10
|
+
initializer "sync.activerecord" do
|
11
|
+
ActiveRecord::Base.send :extend, Model::ClassMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
# Adds the ViewHelpers into ActionView::Base
|
15
|
+
initializer "sync.view_helpers" do
|
16
|
+
ActionView::Base.send :include, ViewHelpers
|
17
|
+
end
|
18
|
+
|
19
|
+
# Adds the ControllerHelpers into ActionConroller::Base
|
20
|
+
initializer "sync.controller_helpers" do
|
21
|
+
ActionController::Base.send :include, RenderSync::ControllerHelpers
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RenderSync
|
2
|
+
tracker_class = nil
|
3
|
+
begin
|
4
|
+
require 'action_view/dependency_tracker'
|
5
|
+
tracker_class = ActionView::DependencyTracker::ERBTracker
|
6
|
+
rescue LoadError
|
7
|
+
begin
|
8
|
+
require 'cache_digests/dependency_tracker'
|
9
|
+
tracker_class = CacheDigests::DependencyTracker::ERBTracker
|
10
|
+
rescue LoadError
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
if tracker_class
|
15
|
+
class ERBTracker < tracker_class
|
16
|
+
# Matches:
|
17
|
+
# sync partial: "comment", collection: commentable.comments
|
18
|
+
# sync partial: "comment", resource: comment
|
19
|
+
SYNC_DEPENDENCY = /
|
20
|
+
sync(?:_new)?\s* # sync or sync_new, followed by optional whitespace
|
21
|
+
\(?\s* # start an optional parenthesis for the sync call
|
22
|
+
(?:partial:|:partial\s+=>)\s* # naming the partial, used with collection
|
23
|
+
["']([a-z][a-z_\/]+)["']\s* # the template name itself -- 1st capture
|
24
|
+
,\s* # comma separating parameters
|
25
|
+
:?(?:resource|collection)(?::|\s+=>)\s* # resource or collection identifier
|
26
|
+
@?(?:[a-z]+\.)*([a-z]+) # the resource or collection itself -- 2nd capture
|
27
|
+
/x
|
28
|
+
|
29
|
+
def self.call(name, template)
|
30
|
+
new(name, template).dependencies
|
31
|
+
end
|
32
|
+
|
33
|
+
def dependencies
|
34
|
+
(sync_dependencies + super).uniq
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def source
|
40
|
+
template.source
|
41
|
+
end
|
42
|
+
|
43
|
+
def sync_dependencies
|
44
|
+
source.scan(SYNC_DEPENDENCY).
|
45
|
+
collect { |template, resource| "sync/#{resource.pluralize}/#{template}" }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module RenderSync
|
2
|
+
class FayeExtension
|
3
|
+
|
4
|
+
def incoming(message, callback)
|
5
|
+
return handle_eror(message, callback) unless message_authenticated?(message)
|
6
|
+
if batch_publish?(message)
|
7
|
+
batch_incoming(message, callback)
|
8
|
+
else
|
9
|
+
single_incoming(message, callback)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def batch_incoming(message, callback)
|
14
|
+
message["data"].each do |message|
|
15
|
+
incoming(message, callback)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def single_incoming(message, callback)
|
20
|
+
callback.call(message)
|
21
|
+
end
|
22
|
+
|
23
|
+
def batch_publish?(message)
|
24
|
+
message['channel'] == "/batch_publish"
|
25
|
+
end
|
26
|
+
|
27
|
+
# IMPORTANT: clear out the auth token so it is not leaked to the client
|
28
|
+
def outgoing(message, callback)
|
29
|
+
if message['ext'] && message['ext']['auth_token']
|
30
|
+
message['ext'] = {}
|
31
|
+
end
|
32
|
+
callback.call(message)
|
33
|
+
end
|
34
|
+
|
35
|
+
def handle_eror(message, callback)
|
36
|
+
message['error'] = 'Invalid authentication token'
|
37
|
+
callback.call(message)
|
38
|
+
end
|
39
|
+
|
40
|
+
def message_authenticated?(message)
|
41
|
+
!(message['channel'] !~ %r{^/meta/} &&
|
42
|
+
message['ext']['auth_token'] != RenderSync.auth_token)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
module RenderSync
|
2
|
+
module Model
|
3
|
+
|
4
|
+
def self.enabled?
|
5
|
+
Thread.current["model_sync_enabled"]
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.context
|
9
|
+
Thread.current["model_sync_context"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.enable!(context = nil)
|
13
|
+
Thread.current["model_sync_enabled"] = true
|
14
|
+
Thread.current["model_sync_context"] = context
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.disable!
|
18
|
+
Thread.current["model_sync_enabled"] = false
|
19
|
+
Thread.current["model_sync_context"] = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.enable(context = nil)
|
23
|
+
enable!(context)
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
disable!
|
27
|
+
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
attr_accessor :sync_default_scope, :sync_scope_definitions, :sync_touches
|
31
|
+
|
32
|
+
# Set up automatic syncing of partials when a record of this class is
|
33
|
+
# created, updated or deleted. Be sure to wrap your model actions inside
|
34
|
+
# a sync_enable block for sync to do its magic.
|
35
|
+
#
|
36
|
+
def sync(*actions)
|
37
|
+
include ModelActions unless include?(ModelActions)
|
38
|
+
include ModelChangeTracking unless include?(ModelChangeTracking)
|
39
|
+
include ModelRenderSyncing
|
40
|
+
|
41
|
+
if actions.last.is_a? Hash
|
42
|
+
@sync_default_scope = actions.last.fetch :default_scope
|
43
|
+
end
|
44
|
+
|
45
|
+
actions = [:create, :update, :destroy] if actions.include? :all
|
46
|
+
actions.flatten!
|
47
|
+
|
48
|
+
if actions.include? :create
|
49
|
+
after_create :prepare_sync_create, if: -> { RenderSync::Model.enabled? }
|
50
|
+
end
|
51
|
+
|
52
|
+
if actions.include? :update
|
53
|
+
after_update :prepare_sync_update, if: -> { RenderSync::Model.enabled? }
|
54
|
+
end
|
55
|
+
|
56
|
+
if actions.include? :destroy
|
57
|
+
after_destroy :prepare_sync_destroy, if: -> { RenderSync::Model.enabled? }
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# Set up a sync scope for the model defining a set of records to be
|
63
|
+
# updated via sync
|
64
|
+
#
|
65
|
+
# name - The name of the scope
|
66
|
+
# lambda - A lambda defining the scope.
|
67
|
+
# Has to return an ActiveRecord::Relation.
|
68
|
+
#
|
69
|
+
# You can define the lambda with arguments (see examples).
|
70
|
+
# Note that the naming of the parameters is very important. Only use
|
71
|
+
# names of methods or ActiveRecord attributes defined on the model (e.g.
|
72
|
+
# user_id). This way sync will be able to pass changed records to the
|
73
|
+
# lambda and track changes to the scope.
|
74
|
+
#
|
75
|
+
# Example:
|
76
|
+
#
|
77
|
+
# class Todo < ActiveRecord::Base
|
78
|
+
# belongs_to :user
|
79
|
+
# belongs_to :project
|
80
|
+
# scope :incomplete, -> { where(complete: false) }
|
81
|
+
#
|
82
|
+
# sync :all
|
83
|
+
#
|
84
|
+
# sync_scope :complete, -> { where(complete: true) }
|
85
|
+
# sync_scope :by_project, ->(project_id) { where(project_id: project_id) }
|
86
|
+
# sync_scope :my_incomplete_todos, ->(user) { incomplete.where(user_id: user.id) }
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# To subscribe to these scopes you would put these lines into your views:
|
90
|
+
#
|
91
|
+
# <%= sync partial: "todo", collection: @todos, scope: Todo.complete %>
|
92
|
+
#
|
93
|
+
# If the collection you want to render is exactly defined be the given
|
94
|
+
# scope the scope can be omitted:
|
95
|
+
#
|
96
|
+
# <%= sync partial: "todo", collection: Todo.complete %>
|
97
|
+
#
|
98
|
+
# For rendering my_incomplete_todos:
|
99
|
+
#
|
100
|
+
# <%= sync partial: "todo", collection: Todo.my_incomplete_todos(current_user) %>
|
101
|
+
#
|
102
|
+
# The render_new call has to look like this:
|
103
|
+
#
|
104
|
+
# <%= sync_new partial: "todo", resource: Todo.new, scope: Todo.complete %>
|
105
|
+
#
|
106
|
+
# Now when a record changes sync will use the names of the lambda
|
107
|
+
# parameters (project_id and user), get the corresponding attributes from
|
108
|
+
# the record (project_id column or user association) and pass it to the
|
109
|
+
# lambda. This way sync can identify if a record has been added or
|
110
|
+
# removed from a scope and will then publish the changes to subscribers
|
111
|
+
# on all scoped channels.
|
112
|
+
#
|
113
|
+
# Beware that chaining of sync scopes in the view is currently not
|
114
|
+
# possible. So the following example would raise an exception:
|
115
|
+
#
|
116
|
+
# <%= sync_new partial: "todo", Todo.new, scope: Todo.mine(current_user).incomplete %>
|
117
|
+
#
|
118
|
+
# To work around this just create an explicit sync_scope for your problem:
|
119
|
+
#
|
120
|
+
# sync_scope :my_incomplete_todos, ->(user) { incomplete.mine(current_user) }
|
121
|
+
#
|
122
|
+
# And in the view:
|
123
|
+
#
|
124
|
+
# <%= sync_new partial: "todo", Todo.new, scope: Todo.my_incomplete_todos(current_user) %>
|
125
|
+
#
|
126
|
+
def sync_scope(name, lambda)
|
127
|
+
if self.respond_to?(name)
|
128
|
+
raise ArgumentError, "invalid scope name '#{name}'. Already defined on #{self.name}"
|
129
|
+
end
|
130
|
+
|
131
|
+
@sync_scope_definitions[name] = RenderSync::ScopeDefinition.new(self, name, lambda)
|
132
|
+
|
133
|
+
singleton_class.send(:define_method, name) do |*args|
|
134
|
+
RenderSync::Scope.new_from_args(@sync_scope_definitions[name], args)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Register one or more associations to be sync'd when this record changes.
|
139
|
+
#
|
140
|
+
# Example:
|
141
|
+
#
|
142
|
+
# class Todo < ActiveRecord::Base
|
143
|
+
# belongs_to :project
|
144
|
+
# belongs_to :user
|
145
|
+
#
|
146
|
+
# sync :all
|
147
|
+
# sync_touch :project, :user
|
148
|
+
# end
|
149
|
+
#
|
150
|
+
def sync_touch(*args)
|
151
|
+
# Only load Modules and set up callbacks if sync_touch wasn't
|
152
|
+
# called before
|
153
|
+
if @sync_touches.blank?
|
154
|
+
include ModelActions unless include?(ModelActions)
|
155
|
+
include ModelChangeTracking unless include?(ModelChangeTracking)
|
156
|
+
include ModelTouching
|
157
|
+
|
158
|
+
@sync_touches ||= []
|
159
|
+
|
160
|
+
after_create :prepare_sync_touches, if: -> { RenderSync::Model.enabled? }
|
161
|
+
after_update :prepare_sync_touches, if: -> { RenderSync::Model.enabled? }
|
162
|
+
after_destroy :prepare_sync_touches, if: -> { RenderSync::Model.enabled? }
|
163
|
+
end
|
164
|
+
|
165
|
+
options = args.extract_options!
|
166
|
+
args.each do |arg|
|
167
|
+
@sync_touches.push(arg)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module RenderSync
|
2
|
+
module ModelActions
|
3
|
+
# Set up instance variable holding the collected sync actions
|
4
|
+
# to be published later on.
|
5
|
+
#
|
6
|
+
attr_accessor :sync_actions
|
7
|
+
|
8
|
+
# Set up ActiveRecord callbacks to prepare for collecting
|
9
|
+
# publish sync actions and publishing them after commit
|
10
|
+
#
|
11
|
+
def self.included(base)
|
12
|
+
base.class_eval do
|
13
|
+
@sync_scope_definitions ||= {}
|
14
|
+
|
15
|
+
before_create :prepare_sync_actions, if: -> { RenderSync::Model.enabled? }
|
16
|
+
before_update :prepare_sync_actions, if: -> { RenderSync::Model.enabled? }
|
17
|
+
before_destroy :prepare_sync_actions, if: -> { RenderSync::Model.enabled? }
|
18
|
+
|
19
|
+
after_commit :publish_sync_actions, if: -> { RenderSync::Model.enabled? }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def sync_default_scope
|
24
|
+
return nil unless self.class.sync_default_scope
|
25
|
+
send self.class.sync_default_scope
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def sync_render_context
|
31
|
+
RenderSync::Model.context || super
|
32
|
+
end
|
33
|
+
|
34
|
+
def prepare_sync_actions
|
35
|
+
self.sync_actions = []
|
36
|
+
end
|
37
|
+
|
38
|
+
# Add a new aync action to the list of actions to be published later on
|
39
|
+
#
|
40
|
+
def add_sync_action(action_name, record, options = {})
|
41
|
+
sync_actions.push(Action.new(record, action_name, options))
|
42
|
+
end
|
43
|
+
|
44
|
+
# Run the collected actions on after_commit callback
|
45
|
+
# Triggers the syncing of the partials
|
46
|
+
#
|
47
|
+
def publish_sync_actions
|
48
|
+
sync_actions.each(&:perform)
|
49
|
+
end
|
50
|
+
|
51
|
+
def sync_scope_definitions
|
52
|
+
self.class.sync_scope_definitions.values
|
53
|
+
end
|
54
|
+
|
55
|
+
def sync_render_context
|
56
|
+
RenderSync::Model.context || super
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|