Class: LiveQuery
Overview
Tracks a channel and a query on a collection. Alerts the listener when the data in the query changes.
Instance Attribute Summary collapse
-
#collection ⇒ Object
readonly
Returns the value of attribute collection.
-
#current_ids ⇒ Object
readonly
Returns the value of attribute current_ids.
-
#query ⇒ Object
readonly
Returns the value of attribute query.
Instance Method Summary collapse
- #add_channel(channel) ⇒ Object
-
#initial_data ⇒ Object
return the query results the first time a channel connects.
-
#initialize(pool, data_store, collection, query) ⇒ LiveQuery
constructor
A new instance of LiveQuery.
- #inspect ⇒ Object
-
#model_class ⇒ Object
Lookup the model class.
-
#model_for_filter(data) ⇒ Object
Takes in data to be sent to the client and sets up a model to test field permissions against.
- #notify!(skip_channel = nil, only_channel = nil) ⇒ Object
- #notify_added(index, data, skip_channel) ⇒ Object
- #notify_changed(id, data, skip_channel) ⇒ Object
- #notify_moved(id, new_position, skip_channel) ⇒ Object
- #notify_removed(ids, skip_channel) ⇒ Object
- #remove_channel(channel) ⇒ Object
- #run(skip_channel = nil) ⇒ Object
Constructor Details
#initialize(pool, data_store, collection, query) ⇒ LiveQuery
Returns a new instance of LiveQuery.
8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'app/volt/tasks/live_query/live_query.rb', line 8 def initialize(pool, data_store, collection, query) @pool = pool @collection = collection @query = query @channels = [] @data_store = data_store @query_tracker = QueryTracker.new(self, @data_store) run end |
Instance Attribute Details
#collection ⇒ Object (readonly)
Returns the value of attribute collection.
6 7 8 |
# File 'app/volt/tasks/live_query/live_query.rb', line 6 def collection @collection end |
#current_ids ⇒ Object (readonly)
Returns the value of attribute current_ids.
6 7 8 |
# File 'app/volt/tasks/live_query/live_query.rb', line 6 def current_ids @current_ids end |
#query ⇒ Object (readonly)
Returns the value of attribute query.
6 7 8 |
# File 'app/volt/tasks/live_query/live_query.rb', line 6 def query @query end |
Instance Method Details
#add_channel(channel) ⇒ Object
89 90 91 |
# File 'app/volt/tasks/live_query/live_query.rb', line 89 def add_channel(channel) @channels << channel end |
#initial_data ⇒ Object
return the query results the first time a channel connects
75 76 77 78 79 80 81 |
# File 'app/volt/tasks/live_query/live_query.rb', line 75 def initial_data @query_tracker.results.map.with_index do |data, index| data = data.dup [index, data] end end |
#inspect ⇒ Object
137 138 139 |
# File 'app/volt/tasks/live_query/live_query.rb', line 137 def inspect "<#{self.class} #{@collection}: #{@query.inspect}>" end |
#model_class ⇒ Object
Lookup the model class
84 85 86 87 |
# File 'app/volt/tasks/live_query/live_query.rb', line 84 def model_class # recreate the "path" from the collection Volt::Model.class_at_path([collection, :[]]) end |
#model_for_filter(data) ⇒ Object
Takes in data to be sent to the client and sets up a model to test field permissions against
122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'app/volt/tasks/live_query/live_query.rb', line 122 def model_for_filter(data) klass = Volt::Model.class_at_path([@collection]) model = nil # Skip read validations when loading the model, no need to check read when checking # permissions. # TODO: We should probably document the possibility of data leak here, though really you # shouldn't be storing anything inside of the permissions block. Volt::Model.no_validate do model = klass.new(data, {}, :loaded) end model end |
#notify!(skip_channel = nil, only_channel = nil) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'app/volt/tasks/live_query/live_query.rb', line 106 def notify!(skip_channel = nil, only_channel = nil) if only_channel channels = [only_channel] else channels = @channels end channels = channels.reject { |c| c == skip_channel } channels.each do |channel| yield(channel) end end |
#notify_added(index, data, skip_channel) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'app/volt/tasks/live_query/live_query.rb', line 32 def notify_added(index, data, skip_channel) # Make model for testing permissions against model = nil notify! do |channel| # Only load the model for filtering if we are sending to a channel # (skip if we are the only one listening) model ||= model_for_filter(data) filtered_data = nil Volt.as_user(channel.user_id) do filtered_data = model.filtered_attributes.sync end channel.('added', nil, @collection, @query, index, filtered_data) end end |
#notify_changed(id, data, skip_channel) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'app/volt/tasks/live_query/live_query.rb', line 57 def notify_changed(id, data, skip_channel) model = nil notify!(skip_channel) do |channel| # Only load the model for filtering if we are sending to a channel # (skip if we are the only one listening) model ||= model_for_filter(data) filtered_data = nil Volt.as_user(channel.user_id) do filtered_data = model.filtered_attributes.sync end # puts "Changed: #{id}, #{data} to #{channel.inspect}" channel.('changed', nil, @collection, @query, id, filtered_data) end end |
#notify_moved(id, new_position, skip_channel) ⇒ Object
50 51 52 53 54 55 |
# File 'app/volt/tasks/live_query/live_query.rb', line 50 def notify_moved(id, new_position, skip_channel) # puts "Moved: #{id}, #{new_position}" notify! do |channel| channel.('moved', nil, @collection, @query, id, new_position) end end |
#notify_removed(ids, skip_channel) ⇒ Object
25 26 27 28 29 30 |
# File 'app/volt/tasks/live_query/live_query.rb', line 25 def notify_removed(ids, skip_channel) # puts "Removed: #{ids.inspect}" notify! do |channel| channel.('removed', nil, @collection, @query, ids) end end |
#remove_channel(channel) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'app/volt/tasks/live_query/live_query.rb', line 93 def remove_channel(channel) deleted = @channels.delete(channel) # remove this query, no one is listening anymore if @channels.empty? begin @pool.remove(@collection, @query) rescue Volt::GenericPoolDeleteException => e # ignore end end end |
#run(skip_channel = nil) ⇒ Object
21 22 23 |
# File 'app/volt/tasks/live_query/live_query.rb', line 21 def run(skip_channel = nil) @query_tracker.run(skip_channel) end |