Class: LiveRecord::AutoloadsChannel
- Inherits:
-
BaseChannel
- Object
- ActionCable::Channel::Base
- BaseChannel
- LiveRecord::AutoloadsChannel
- Defined in:
- app/channels/live_record/autoloads_channel.rb
Instance Method Summary collapse
- #subscribed ⇒ Object
-
#sync_records(data) ⇒ Object
TODO: split up sync_records action because it currently both handles “syncing” and “reloading”.
Instance Method Details
#subscribed ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'app/channels/live_record/autoloads_channel.rb', line 2 def subscribed stream_from 'live_record:autoloads', coder: ActiveSupport::JSON do || new_or_updated_record = ['model_name'].safe_constantize.find_by(id: ['record_id']) || break new_or_changed_attributes = .fetch('attributes') is_autoload_dependent_to_new_or_changed_attributes = false conditions_hash = params[:where].to_h # if no conditions supplied to autoload(), then it means every attribute is dependent if conditions_hash.empty? is_autoload_dependent_to_new_or_changed_attributes = true else @autoload_dependent_attributes ||= [].tap do |autoload_dependent_attributes| conditions_hash.each do |key, value| operator = key.split('_').last # to get attribute_name, we subtract the end part of the string with size of operator substring; i.e.: created_at_lteq -> created_at attribute_name = key[0..(-1 - operator.size - 1)] autoload_dependent_attributes << attribute_name end end @autoload_dependent_attributes.each do |autoload_dependent_attribute| if new_or_changed_attributes.include? autoload_dependent_attribute is_autoload_dependent_to_new_or_changed_attributes = true break end end end # now if this autoload subscription is indeed dependent on the attributes, # then we now check if the where condition values actually match # and then transmit data if authorised attributes match condition values if is_autoload_dependent_to_new_or_changed_attributes model_class = params[:model_name].safe_constantize active_record_relation = LiveRecord::BaseChannel::SearchAdapters.mapped_active_record_relation( model_class: model_class, conditions_hash: conditions_hash, current_user: current_user, ) if active_record_relation.exists?(id: new_or_updated_record.id) whitelisted_attributes = LiveRecord::BaseChannel::Helpers.whitelisted_attributes(new_or_updated_record, current_user) if whitelisted_attributes.size > 0 = { 'action' => 'createOrUpdate', 'attributes' => new_or_updated_record.attributes } response = (, whitelisted_attributes) transmit response if response.present? end end end end end |
#sync_records(data) ⇒ Object
TODO: split up sync_records action because it currently both handles “syncing” and “reloading”
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'app/channels/live_record/autoloads_channel.rb', line 59 def sync_records(data) params = data.symbolize_keys model_class = params[:model_name].safe_constantize if model_class && model_class < ApplicationRecord is_being_reloaded = params[:stale_since].blank? is_being_synced = params[:stale_since].present? active_record_relation = LiveRecord::BaseChannel::SearchAdapters.mapped_active_record_relation( model_class: model_class, conditions_hash: params[:where].to_h, current_user: current_user, ) if is_being_synced active_record_relation = active_record_relation.where( 'updated_at >= ?', DateTime.parse(params[:stale_since]) - LiveRecord.configuration.sync_record_buffer_time ) end # we `transmmit` a message back to client for each matching record active_record_relation.find_each do |record| # but first, check for the authorised attributes, if exists whitelisted_attributes = LiveRecord::BaseChannel::Helpers.whitelisted_attributes(record, current_user) if whitelisted_attributes.size > 0 = { 'action' => 'createOrUpdate', 'attributes' => record.attributes } response = (, whitelisted_attributes) transmit response if response.present? end end # if being reloaded, we finally still transmit a "done" action indicating that reloading has just finished if is_being_reloaded response = { 'action' => 'afterReload', 'recordIds' => active_record_relation.pluck(:id) } transmit response end else respond_with_error(:bad_request, 'Not a correct model name') reject_subscription end end |