cable_ready 5.0.0.pre0 → 5.0.0.pre4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +87 -8
- data/Gemfile.lock +105 -97
- data/README.md +10 -6
- data/app/channels/cable_ready/stream.rb +12 -0
- data/app/helpers/cable_ready_helper.rb +24 -0
- data/app/jobs/cable_ready_broadcast_job.rb +14 -0
- data/app/models/concerns/cable_ready/updatable/collection_updatable_callbacks.rb +19 -0
- data/app/models/concerns/cable_ready/updatable/collections_registry.rb +33 -0
- data/app/models/concerns/cable_ready/updatable/model_updatable_callbacks.rb +28 -0
- data/app/models/concerns/cable_ready/updatable.rb +98 -0
- data/app/models/concerns/extend_has_many.rb +13 -0
- data/lib/cable_ready/channels.rb +1 -1
- data/lib/cable_ready/compoundable.rb +1 -1
- data/lib/cable_ready/config.rb +2 -0
- data/lib/cable_ready/identifiable.rb +13 -2
- data/lib/cable_ready/operation_builder.rb +25 -14
- data/lib/cable_ready/sanity_checker.rb +50 -50
- data/lib/cable_ready/version.rb +1 -1
- data/lib/cable_ready.rb +3 -0
- data/lib/generators/cable_ready/{stream_from_generator.rb → helpers_generator.rb} +1 -1
- data/test/dummy/app/channels/application_cable/channel.rb +4 -0
- data/test/dummy/app/channels/application_cable/connection.rb +4 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +7 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/application_record.rb +3 -0
- data/test/dummy/app/models/global_idable_entity.rb +16 -0
- data/test/dummy/app/models/post.rb +4 -0
- data/test/dummy/app/models/section.rb +6 -0
- data/test/dummy/app/models/team.rb +6 -0
- data/test/dummy/app/models/topic.rb +4 -0
- data/test/dummy/app/models/user.rb +7 -0
- data/test/dummy/config/application.rb +22 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +76 -0
- data/test/dummy/config/environments/production.rb +120 -0
- data/test/dummy/config/environments/test.rb +59 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +12 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +8 -0
- data/test/dummy/config/initializers/cable_ready.rb +18 -0
- data/test/dummy/config/initializers/content_security_policy.rb +28 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/permissions_policy.rb +11 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/puma.rb +43 -0
- data/test/dummy/config/routes.rb +3 -0
- data/test/dummy/db/migrate/20210902154139_create_users.rb +9 -0
- data/test/dummy/db/migrate/20210902154153_create_posts.rb +10 -0
- data/test/dummy/db/migrate/20210904081930_create_topics.rb +9 -0
- data/test/dummy/db/migrate/20210904093607_create_sections.rb +9 -0
- data/test/dummy/db/migrate/20210913191735_create_teams.rb +8 -0
- data/test/dummy/db/migrate/20210913191759_add_team_reference_to_users.rb +5 -0
- data/test/dummy/db/schema.rb +49 -0
- data/test/dummy/test/models/post_test.rb +7 -0
- data/test/dummy/test/models/section_test.rb +7 -0
- data/test/dummy/test/models/team_test.rb +7 -0
- data/test/dummy/test/models/topic_test.rb +7 -0
- data/test/dummy/test/models/user_test.rb +7 -0
- data/test/lib/cable_ready/cable_car_test.rb +25 -3
- data/test/lib/cable_ready/compoundable_test.rb +26 -0
- data/test/lib/cable_ready/helper_test.rb +25 -0
- data/test/lib/cable_ready/identifiable_test.rb +0 -6
- data/test/lib/cable_ready/operation_builder_test.rb +89 -28
- data/test/lib/cable_ready/updatable_test.rb +112 -0
- data/test/test_helper.rb +4 -1
- metadata +126 -14
- data/cable_ready.gemspec +0 -27
- data/package.json +0 -39
- data/tags +0 -80
- data/yarn.lock +0 -2562
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CableReady
|
4
|
+
module Updatable
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do |base|
|
8
|
+
if base < ActiveRecord::Base
|
9
|
+
include ExtendHasMany
|
10
|
+
|
11
|
+
after_commit CollectionUpdatableCallbacks.new(:create), on: :create
|
12
|
+
after_commit CollectionUpdatableCallbacks.new(:update), on: :update
|
13
|
+
after_commit CollectionUpdatableCallbacks.new(:destroy), on: :destroy
|
14
|
+
|
15
|
+
def self.enable_updates(*options)
|
16
|
+
options = options.extract_options!
|
17
|
+
options = {
|
18
|
+
on: [:create, :update, :destroy],
|
19
|
+
if: -> { true }
|
20
|
+
}.merge(options)
|
21
|
+
|
22
|
+
enabled_operations = Array(options[:on])
|
23
|
+
|
24
|
+
after_commit(ModelUpdatableCallbacks.new(:create, enabled_operations), {on: :create, if: options[:if]})
|
25
|
+
after_commit(ModelUpdatableCallbacks.new(:update, enabled_operations), {on: :update, if: options[:if]})
|
26
|
+
after_commit(ModelUpdatableCallbacks.new(:destroy, enabled_operations), {on: :destroy, if: options[:if]})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
def has_many(name, scope = nil, **options, &extension)
|
35
|
+
option = options.delete(:enable_updates)
|
36
|
+
broadcast = option.present?
|
37
|
+
result = super
|
38
|
+
enrich_association_with_updates(name, option) if broadcast
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
def cable_ready_collections
|
43
|
+
@cable_ready_collections ||= CollectionsRegistry.new
|
44
|
+
end
|
45
|
+
|
46
|
+
def cable_ready_update_collection(resource, name)
|
47
|
+
identifier = resource.to_global_id.to_s + ":" + name.to_s
|
48
|
+
ActionCable.server.broadcast(identifier, {})
|
49
|
+
end
|
50
|
+
|
51
|
+
def enrich_association_with_updates(name, option)
|
52
|
+
reflection = reflect_on_association(name)
|
53
|
+
|
54
|
+
inverse_of = reflection.inverse_of&.name&.to_s
|
55
|
+
through_association = nil
|
56
|
+
|
57
|
+
if reflection.through_reflection?
|
58
|
+
inverse_of = reflection.through_reflection.inverse_of&.name&.to_s
|
59
|
+
through_association = reflection.through_reflection.name.to_s.singularize
|
60
|
+
end
|
61
|
+
|
62
|
+
options = {
|
63
|
+
on: [:create, :update, :destroy],
|
64
|
+
if: ->(resource) { true }
|
65
|
+
}
|
66
|
+
|
67
|
+
case option
|
68
|
+
when TrueClass
|
69
|
+
# proceed!
|
70
|
+
when FalseClass
|
71
|
+
options[:on] = []
|
72
|
+
when Array
|
73
|
+
options[:on] = option
|
74
|
+
when Symbol
|
75
|
+
options[:on] = [option]
|
76
|
+
when Hash
|
77
|
+
option[:on] = Array(option[:on]) if option[:on]
|
78
|
+
options = options.merge!(option)
|
79
|
+
when Proc
|
80
|
+
options[:if] = option
|
81
|
+
else
|
82
|
+
raise ArgumentError, "Invalid enable_updates option #{option}"
|
83
|
+
end
|
84
|
+
|
85
|
+
reflection.klass.send(:include, CableReady::Updatable) unless reflection.klass.respond_to?(:cable_ready_collections)
|
86
|
+
|
87
|
+
reflection.klass.cable_ready_collections.register({
|
88
|
+
klass: self,
|
89
|
+
foreign_key: reflection.foreign_key,
|
90
|
+
name: name,
|
91
|
+
inverse_association: inverse_of,
|
92
|
+
through_association: through_association,
|
93
|
+
options: options
|
94
|
+
})
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ExtendHasMany
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
class_methods do
|
7
|
+
def has_many(*args, &block)
|
8
|
+
options = args.extract_options!
|
9
|
+
options[:extend] = Array(options[:extend]).push(ClassMethods)
|
10
|
+
super(*args, **options, &block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/cable_ready/channels.rb
CHANGED
@@ -13,7 +13,7 @@ module CableReady
|
|
13
13
|
|
14
14
|
def [](*keys)
|
15
15
|
keys.select!(&:itself)
|
16
|
-
identifier = keys.many? || (keys.one? && keys.first.
|
16
|
+
identifier = keys.many? || (keys.one? && keys.first.respond_to?(:to_global_id)) ? compound(keys) : keys.pop
|
17
17
|
@channels[identifier] ||= CableReady::Channel.new(identifier)
|
18
18
|
end
|
19
19
|
|
data/lib/cable_ready/config.rb
CHANGED
@@ -3,9 +3,13 @@
|
|
3
3
|
module CableReady
|
4
4
|
module Identifiable
|
5
5
|
def dom_id(record, prefix = nil)
|
6
|
+
return record.to_dom_selector if record.respond_to?(:to_dom_selector)
|
7
|
+
|
6
8
|
prefix = prefix.to_s.strip if prefix
|
7
9
|
|
8
|
-
id = if record.
|
10
|
+
id = if record.respond_to?(:to_dom_id)
|
11
|
+
record.to_dom_id
|
12
|
+
elsif record.is_a?(ActiveRecord::Relation)
|
9
13
|
[prefix, record.model_name.plural].compact.join("_")
|
10
14
|
elsif record.is_a?(ActiveRecord::Base)
|
11
15
|
ActionView::RecordIdentifier.dom_id(record, prefix)
|
@@ -13,7 +17,14 @@ module CableReady
|
|
13
17
|
[prefix, record.to_s.strip].compact.join("_")
|
14
18
|
end
|
15
19
|
|
16
|
-
"##{id}".squeeze("#").strip
|
20
|
+
"##{id}".squeeze("#").strip.downcase
|
21
|
+
end
|
22
|
+
|
23
|
+
def identifiable?(obj)
|
24
|
+
obj.respond_to?(:to_dom_selector) ||
|
25
|
+
obj.respond_to?(:to_dom_id) ||
|
26
|
+
obj.is_a?(ActiveRecord::Relation) ||
|
27
|
+
obj.is_a?(ActiveRecord::Base)
|
17
28
|
end
|
18
29
|
end
|
19
30
|
end
|
@@ -24,17 +24,32 @@ module CableReady
|
|
24
24
|
def add_operation_method(name)
|
25
25
|
return if respond_to?(name)
|
26
26
|
singleton_class.public_send :define_method, name, ->(*args) {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
if args.one? && args.first.respond_to?(:to_operation_options) && [Array, Hash].include?(args.first.to_operation_options.class)
|
28
|
+
case args.first.to_operation_options
|
29
|
+
when Array
|
30
|
+
selector, options = nil, args.first.to_operation_options
|
31
|
+
.select { |e| e.is_a?(Symbol) && args.first.respond_to?("to_#{e}".to_sym) }
|
32
|
+
.each_with_object({}) { |option, memo| memo[option.to_s] = args.first.send("to_#{option}".to_sym) }
|
33
|
+
when Hash
|
34
|
+
selector, options = nil, args.first.to_operation_options
|
35
|
+
else
|
36
|
+
raise TypeError, ":to_operation_options returned an #{args.first.to_operation_options.class.name}. Must be an Array or Hash."
|
37
|
+
end
|
38
|
+
else
|
39
|
+
selector, options = nil, args.first || {} # 1 or 0 params
|
40
|
+
selector, options = options, {} unless options.is_a?(Hash) # swap if only selector provided
|
41
|
+
selector, options = args[0, 2] if args.many? # 2 or more params
|
42
|
+
options.stringify_keys!
|
43
|
+
options.each { |key, value| options[key] = value.send("to_#{key}".to_sym) if value.respond_to?("to_#{key}".to_sym) }
|
44
|
+
end
|
31
45
|
options["selector"] = selector if selector && options.exclude?("selector")
|
32
46
|
options["selector"] = previous_selector if previous_selector && options.exclude?("selector")
|
33
47
|
if options.include?("selector")
|
34
48
|
@previous_selector = options["selector"]
|
35
|
-
options["selector"] =
|
49
|
+
options["selector"] = identifiable?(previous_selector) ? dom_id(previous_selector) : previous_selector
|
36
50
|
end
|
37
|
-
|
51
|
+
options["operation"] = name.to_s.camelize(:lower)
|
52
|
+
@enqueued_operations << options
|
38
53
|
self
|
39
54
|
}
|
40
55
|
end
|
@@ -43,26 +58,22 @@ module CableReady
|
|
43
58
|
@enqueued_operations.to_json(*args)
|
44
59
|
end
|
45
60
|
|
46
|
-
def apply!(operations = "
|
61
|
+
def apply!(operations = "[]")
|
47
62
|
operations = begin
|
48
63
|
JSON.parse(operations.is_a?(String) ? operations : operations.to_json)
|
49
64
|
rescue JSON::ParserError
|
50
65
|
{}
|
51
66
|
end
|
52
|
-
operations
|
53
|
-
operation.each do |enqueued_operation|
|
54
|
-
@enqueued_operations[name.to_s] << enqueued_operation
|
55
|
-
end
|
56
|
-
end
|
67
|
+
@enqueued_operations.push(operations)
|
57
68
|
self
|
58
69
|
end
|
59
70
|
|
60
71
|
def operations_payload
|
61
|
-
@enqueued_operations.
|
72
|
+
@enqueued_operations.map { |operation| operation.deep_transform_keys! { |key| key.to_s.camelize(:lower) } }
|
62
73
|
end
|
63
74
|
|
64
75
|
def reset!
|
65
|
-
@enqueued_operations =
|
76
|
+
@enqueued_operations = []
|
66
77
|
@previous_selector = nil
|
67
78
|
end
|
68
79
|
end
|
@@ -7,48 +7,59 @@ class CableReady::SanityChecker
|
|
7
7
|
|
8
8
|
class << self
|
9
9
|
def check!
|
10
|
+
return if ENV["SKIP_SANITY_CHECK"]
|
10
11
|
return if CableReady.config.on_failed_sanity_checks == :ignore
|
11
12
|
return if called_by_generate_config?
|
13
|
+
return if called_by_rake?
|
12
14
|
|
13
15
|
instance = new
|
14
|
-
instance.
|
16
|
+
instance.check_package_versions_match
|
15
17
|
instance.check_new_version_available
|
16
18
|
end
|
17
19
|
|
18
20
|
private
|
19
21
|
|
20
22
|
def called_by_generate_config?
|
21
|
-
ARGV.include?
|
23
|
+
ARGV.include?("cable_ready:initializer")
|
24
|
+
end
|
25
|
+
|
26
|
+
def called_by_rake?
|
27
|
+
File.basename($PROGRAM_NAME) == "rake"
|
22
28
|
end
|
23
29
|
end
|
24
30
|
|
25
|
-
def
|
26
|
-
if
|
31
|
+
def check_package_versions_match
|
32
|
+
if npm_version.nil?
|
27
33
|
warn_and_exit <<~WARN
|
28
|
-
Can't locate the cable_ready npm package.
|
34
|
+
👉 Can't locate the cable_ready npm package.
|
35
|
+
|
36
|
+
yarn add cable_ready@#{gem_version}
|
37
|
+
|
29
38
|
Either add it to your package.json as a dependency or use "yarn link cable_ready" if you are doing development.
|
30
39
|
WARN
|
31
40
|
end
|
32
41
|
|
33
|
-
|
42
|
+
if package_version_mismatch?
|
34
43
|
warn_and_exit <<~WARN
|
35
|
-
The cable_ready npm package version (#{
|
44
|
+
👉 The cable_ready npm package version (#{npm_version}) does not match the Rubygem version (#{gem_version}).
|
45
|
+
|
36
46
|
To update the cable_ready npm package:
|
47
|
+
|
37
48
|
yarn upgrade cable_ready@#{gem_version}
|
38
49
|
WARN
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
42
53
|
def check_new_version_available
|
43
|
-
return unless Rails.env.development?
|
44
54
|
return if CableReady.config.on_new_version_available == :ignore
|
45
|
-
return
|
55
|
+
return if Rails.env.development? == false
|
56
|
+
return if using_preview_release?
|
46
57
|
begin
|
47
58
|
latest_version = URI.open("https://raw.githubusercontent.com/stimulusreflex/cable_ready/master/LATEST", open_timeout: 1, read_timeout: 1).read.strip
|
48
59
|
if latest_version != CableReady::VERSION
|
49
60
|
puts <<~WARN
|
50
61
|
|
51
|
-
There is a new version of CableReady available!
|
62
|
+
👉 There is a new version of CableReady available!
|
52
63
|
Current: #{CableReady::VERSION} Latest: #{latest_version}
|
53
64
|
|
54
65
|
If you upgrade, it is very important that you update BOTH Gemfile and package.json
|
@@ -58,31 +69,31 @@ class CableReady::SanityChecker
|
|
58
69
|
exit if CableReady.config.on_new_version_available == :exit
|
59
70
|
end
|
60
71
|
rescue
|
61
|
-
puts "CableReady #{CableReady::VERSION} update check skipped: connection timeout"
|
72
|
+
puts "👉 CableReady #{CableReady::VERSION} update check skipped: connection timeout"
|
62
73
|
end
|
63
74
|
end
|
64
75
|
|
65
76
|
private
|
66
77
|
|
67
|
-
def
|
68
|
-
|
78
|
+
def package_version_mismatch?
|
79
|
+
npm_version != gem_version
|
69
80
|
end
|
70
81
|
|
71
|
-
def
|
72
|
-
|
73
|
-
puts "CableReady #{CableReady::VERSION} update check skipped: pre-release build"
|
74
|
-
|
82
|
+
def using_preview_release?
|
83
|
+
preview = CableReady::VERSION.match?(LATEST_VERSION_FORMAT) == false
|
84
|
+
puts "👉 CableReady #{CableReady::VERSION} update check skipped: pre-release build" if preview
|
85
|
+
preview
|
75
86
|
end
|
76
87
|
|
77
88
|
def gem_version
|
78
89
|
@_gem_version ||= CableReady::VERSION.gsub(".pre", "-pre")
|
79
90
|
end
|
80
91
|
|
81
|
-
def
|
82
|
-
@
|
92
|
+
def npm_version
|
93
|
+
@_npm_version ||= find_npm_version
|
83
94
|
end
|
84
95
|
|
85
|
-
def
|
96
|
+
def find_npm_version
|
86
97
|
if (match = search_file(package_json_path, regex: /version/))
|
87
98
|
match[JSON_VERSION_FORMAT, 1]
|
88
99
|
elsif (match = search_file(yarn_lock_path, regex: /^cable_ready/))
|
@@ -91,7 +102,7 @@ class CableReady::SanityChecker
|
|
91
102
|
end
|
92
103
|
|
93
104
|
def search_file(path, regex:)
|
94
|
-
return
|
105
|
+
return if File.exist?(path) == false
|
95
106
|
File.foreach(path).grep(regex).first
|
96
107
|
end
|
97
108
|
|
@@ -103,49 +114,38 @@ class CableReady::SanityChecker
|
|
103
114
|
Rails.root.join("yarn.lock")
|
104
115
|
end
|
105
116
|
|
106
|
-
def
|
107
|
-
|
117
|
+
def initializer_missing?
|
118
|
+
File.exist?(Rails.root.join("config", "initializers", "cable_ready.rb")) == false
|
108
119
|
end
|
109
120
|
|
110
121
|
def warn_and_exit(text)
|
111
|
-
puts
|
122
|
+
puts
|
123
|
+
puts "Heads up! 🔥"
|
124
|
+
puts
|
112
125
|
puts text
|
113
|
-
exit_with_info if CableReady.config.on_failed_sanity_checks == :exit
|
114
|
-
end
|
115
|
-
|
116
|
-
def exit_with_info
|
117
126
|
puts
|
118
|
-
|
119
|
-
if File.exist?(initializer_path)
|
127
|
+
if CableReady.config.on_failed_sanity_checks == :exit
|
120
128
|
puts <<~INFO
|
121
|
-
|
122
|
-
you can add the following directive to the CableReady initializer,
|
123
|
-
which is located at #{initializer_path}
|
129
|
+
To ignore any warnings and start the application anyway, you can set the SKIP_SANITY_CHECK environment variable:
|
124
130
|
|
125
|
-
|
126
|
-
config.on_failed_sanity_checks = :warn
|
127
|
-
end
|
128
|
-
|
129
|
-
INFO
|
130
|
-
else
|
131
|
-
puts <<~INFO
|
132
|
-
If you know what you are doing and you want to start the application anyway,
|
133
|
-
you can create a CableReady initializer with the command:
|
134
|
-
|
135
|
-
bundle exec rails generate cable_ready:config
|
131
|
+
SKIP_SANITY_CHECK=true rails
|
136
132
|
|
137
|
-
|
138
|
-
|
139
|
-
#{initializer_path}
|
140
|
-
|
141
|
-
and then add the following directive:
|
133
|
+
To do this permanently, add the following directive to the CableReady initializer:
|
142
134
|
|
143
135
|
CableReady.configure do |config|
|
144
136
|
config.on_failed_sanity_checks = :warn
|
145
137
|
end
|
146
138
|
|
147
139
|
INFO
|
140
|
+
if initializer_missing?
|
141
|
+
puts <<~INFO
|
142
|
+
You can create a CableReady initializer with the command:
|
143
|
+
|
144
|
+
bundle exec rails generate cable_ready:initializer
|
145
|
+
|
146
|
+
INFO
|
147
|
+
end
|
148
|
+
exit false if Rails.env.test? == false
|
148
149
|
end
|
149
|
-
exit false unless Rails.env.test?
|
150
150
|
end
|
151
151
|
end
|
data/lib/cable_ready/version.rb
CHANGED
data/lib/cable_ready.rb
CHANGED
@@ -30,8 +30,11 @@ module CableReady
|
|
30
30
|
initializer "renderer" do
|
31
31
|
ActiveSupport.on_load(:action_controller) do
|
32
32
|
ActionController::Renderers.add :operations do |operations, options|
|
33
|
+
response.content_type ||= Mime[:cable_ready]
|
33
34
|
render json: operations.dispatch
|
34
35
|
end
|
36
|
+
|
37
|
+
Mime::Type.register "application/vnd.cable-ready.json", :cable_ready
|
35
38
|
end
|
36
39
|
end
|
37
40
|
end
|
@@ -4,7 +4,7 @@ require "rails/generators"
|
|
4
4
|
require "fileutils"
|
5
5
|
|
6
6
|
module CableReady
|
7
|
-
class
|
7
|
+
class HelpersGenerator < Rails::Generators::Base
|
8
8
|
desc "Initializes CableReady with a reference to the shared ActionCable consumer"
|
9
9
|
source_root File.expand_path("templates", __dir__)
|
10
10
|
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class ApplicationJob < ActiveJob::Base
|
2
|
+
# Automatically retry jobs that encountered a deadlock
|
3
|
+
# retry_on ActiveRecord::Deadlocked
|
4
|
+
|
5
|
+
# Most jobs are safe to ignore if the underlying records are no longer available
|
6
|
+
# discard_on ActiveJob::DeserializationError
|
7
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class GlobalIdableEntity
|
2
|
+
include GlobalID::Identification
|
3
|
+
include CableReady::Updatable
|
4
|
+
|
5
|
+
def id
|
6
|
+
"fake-id"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.find(id)
|
10
|
+
new if id == "fake-id"
|
11
|
+
end
|
12
|
+
|
13
|
+
def fake_update
|
14
|
+
ModelUpdatableCallbacks.new(:update).after_commit(self)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative "boot"
|
2
|
+
|
3
|
+
require "rails/all"
|
4
|
+
|
5
|
+
# Require the gems listed in Gemfile, including any gems
|
6
|
+
# you've limited to :test, :development, or :production.
|
7
|
+
Bundler.require(*Rails.groups)
|
8
|
+
require "cable_ready"
|
9
|
+
|
10
|
+
module Dummy
|
11
|
+
class Application < Rails::Application
|
12
|
+
config.load_defaults Rails::VERSION::STRING.to_f
|
13
|
+
|
14
|
+
# Configuration for the application, engines, and railties goes here.
|
15
|
+
#
|
16
|
+
# These settings can be overridden in specific environments using the files
|
17
|
+
# in config/environments, which are processed later.
|
18
|
+
#
|
19
|
+
# config.time_zone = "Central Time (US & Canada)"
|
20
|
+
# config.eager_load_paths << Rails.root.join("extras")
|
21
|
+
end
|
22
|
+
end
|