Module: CableReady::Updatable::ClassMethods

Includes:
Compoundable
Defined in:
app/models/concerns/cable_ready/updatable.rb

Instance Method Summary collapse

Methods included from Compoundable

#compound

Instance Method Details

#broadcast_updates(model_class, options) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'app/models/concerns/cable_ready/updatable.rb', line 183

def broadcast_updates(model_class, options)
  return if skip_updates_classes.any? { |klass| klass >= self }
  raise("ActionCable must be enabled to use Updatable") unless defined?(ActionCable)

  debounce_time = options.delete(:debounce)
  debounce_time ||= CableReady.config.updatable_debounce_time

  if debounce_time.to_f > 0
    key = compound([model_class, *options])
    old_wait_until = CableReady.config.updatable_debounce_adapter[key]
    now = Time.now.to_f

    if old_wait_until.nil? || old_wait_until < now
      new_wait_until = now + debounce_time.to_f
      CableReady.config.updatable_debounce_adapter[key] = new_wait_until
      ActionCable.server.broadcast(model_class, options)
    end
  else
    ActionCable.server.broadcast(model_class, options)
  end
end

#build_options(option) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'app/models/concerns/cable_ready/updatable.rb', line 156

def build_options(option)
  options = {
    on: [:create, :update, :destroy],
    if: ->(resource) { true }
  }

  case option
  when TrueClass
  # proceed!
  when FalseClass
    options[:on] = []
  when Array
    options[:on] = option
  when Symbol
    options[:on] = [option]
  when Hash
    option[:on] = Array(option[:on]) if option[:on]
    options = options.merge!(option)
  when Proc
    options[:if] = option
  else
    raise ArgumentError, "Invalid enable_cable_ready_updates option #{option}"
  end

  options
end

#cable_ready_collectionsObject



111
112
113
# File 'app/models/concerns/cable_ready/updatable.rb', line 111

def cable_ready_collections
  @cable_ready_collections ||= CollectionsRegistry.new
end

#cable_ready_update_collection(resource, name, model, debounce: CableReady.config.updatable_debounce_time) ⇒ Object



115
116
117
118
119
120
121
# File 'app/models/concerns/cable_ready/updatable.rb', line 115

def cable_ready_update_collection(resource, name, model, debounce: CableReady.config.updatable_debounce_time)
  identifier = resource.to_global_id.to_s + ":" + name.to_s
  changeset = model.respond_to?(:previous_changes) ? {changed: model.previous_changes.keys} : {}
  options = changeset.merge({debounce: debounce})

  broadcast_updates(identifier, options)
end

#enrich_association_with_updates(name, option, descendants = nil, debounce: CableReady.config.updatable_debounce_time) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'app/models/concerns/cable_ready/updatable.rb', line 123

def enrich_association_with_updates(name, option, descendants = nil, debounce: CableReady.config.updatable_debounce_time)
  reflection = reflect_on_association(name)

  options = build_options(option)

  [reflection.klass, *descendants&.map(&:to_s)&.map(&:constantize)].each do |klass|
    klass.send(:include, CableReady::Updatable) unless klass.respond_to?(:cable_ready_collections)
    klass.cable_ready_collections.register(Collection.new(
      klass: self,
      name: name,
      options: options,
      reflection: reflection,
      debounce_time: debounce
    ))
  end
end

#enrich_attachments_with_updates(name, option, debounce: CableReady.config.updatable_debounce_time) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'app/models/concerns/cable_ready/updatable.rb', line 140

def enrich_attachments_with_updates(name, option, debounce: CableReady.config.updatable_debounce_time)
  options = build_options(option)

  ActiveStorage::Attachment.send(:include, CableReady::Updatable) unless ActiveStorage::Attachment.respond_to?(:cable_ready_collections)

  ActiveStorage::Attachment.cable_ready_collections.register(Collection.new(
    klass: self,
    foreign_key: "record_id",
    name: name,
    inverse_association: "record",
    through_association: nil,
    options: options,
    debounce_time: debounce
  ))
end

#has_many(name, scope = nil, **options, &extension) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'app/models/concerns/cable_ready/updatable.rb', line 59

def has_many(name, scope = nil, **options, &extension)
  option = if options.has_key?(:enable_updates)
    warn "DEPRECATED: please use `enable_cable_ready_updates` instead. The `enable_updates` option will be removed from a future version of CableReady 5"
    options.delete(:enable_updates)
  else
    options.delete(:enable_cable_ready_updates)
  end

  descendants = options.delete(:descendants)
  debounce_time = options.delete(:debounce)

  broadcast = option.present?
  result = super
  enrich_association_with_updates(name, option, descendants, debounce: debounce_time) if broadcast
  result
end

#has_many_attached(name, **options) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'app/models/concerns/cable_ready/updatable.rb', line 93

def has_many_attached(name, **options)
  raise("ActiveStorage must be enabled to use has_many_attached") unless defined?(ActiveStorage)

  option = if options.has_key?(:enable_updates)
    warn "DEPRECATED: please use `enable_cable_ready_updates` instead. The `enable_updates` option will be removed from a future version of CableReady 5"
    options.delete(:enable_updates)
  else
    options.delete(:enable_cable_ready_updates)
  end

  debounce_time = options.delete(:debounce)

  broadcast = option.present?
  result = super
  enrich_attachments_with_updates(name, option, debounce: debounce_time) if broadcast
  result
end

#has_one(name, scope = nil, **options, &extension) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'app/models/concerns/cable_ready/updatable.rb', line 76

def has_one(name, scope = nil, **options, &extension)
  option = if options.has_key?(:enable_updates)
    warn "DEPRECATED: please use `enable_cable_ready_updates` instead. The `enable_updates` option will be removed from a future version of CableReady 5"
    options.delete(:enable_updates)
  else
    options.delete(:enable_cable_ready_updates)
  end

  descendants = options.delete(:descendants)
  debounce_time = options.delete(:debounce)

  broadcast = option.present?
  result = super
  enrich_association_with_updates(name, option, descendants, debounce: debounce_time) if broadcast
  result
end

#skip_updates_classesObject



205
206
207
# File 'app/models/concerns/cable_ready/updatable.rb', line 205

def skip_updates_classes
  Thread.current[:skip_updates_classes] ||= []
end