anycable-rails 1.0.0.preview2 → 1.0.0.rc1
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 +14 -125
- data/README.md +14 -34
- data/lib/anycable/rails.rb +36 -2
- data/lib/anycable/rails/actioncable/channel.rb +4 -0
- data/lib/anycable/rails/actioncable/connection.rb +24 -35
- data/lib/anycable/rails/actioncable/connection/serializable_identification.rb +42 -0
- data/lib/anycable/rails/actioncable/remote_connections.rb +11 -0
- data/lib/anycable/rails/channel_state.rb +48 -0
- data/lib/anycable/rails/compatibility.rb +4 -7
- data/lib/anycable/rails/compatibility/rubocop.rb +0 -1
- data/lib/anycable/rails/compatibility/rubocop/config/default.yml +3 -0
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/instance_vars.rb +1 -1
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/stream_from.rb +4 -4
- data/lib/anycable/rails/railtie.rb +10 -10
- data/lib/anycable/rails/refinements/subscriptions.rb +5 -0
- data/lib/anycable/rails/session_proxy.rb +19 -2
- data/lib/anycable/rails/version.rb +1 -1
- data/lib/generators/anycable/download/USAGE +14 -0
- data/lib/generators/anycable/download/download_generator.rb +77 -0
- data/lib/generators/anycable/setup/USAGE +2 -0
- data/lib/{rails/generators → generators}/anycable/setup/setup_generator.rb +67 -89
- data/lib/{rails/generators → generators}/anycable/setup/templates/Procfile.dev +0 -0
- data/lib/{rails/generators → generators}/anycable/setup/templates/config/anycable.yml.tt +12 -1
- data/lib/generators/anycable/setup/templates/config/cable.yml.tt +11 -0
- data/lib/{rails/generators/anycable/setup/templates/config/initializers/anycable.rb → generators/anycable/setup/templates/config/initializers/anycable.rb.tt} +1 -1
- data/lib/generators/anycable/with_os_helpers.rb +55 -0
- metadata +23 -47
- data/lib/anycable/rails/compatibility/rubocop/cops/anycable/remote_disconnect.rb +0 -31
- data/lib/rails/generators/anycable/setup/templates/Procfile +0 -2
- data/lib/rails/generators/anycable/setup/templates/bin/heroku-web +0 -7
- data/lib/rails/generators/anycable/setup/templates/config/cable.yml.tt +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36b6e47a498bfc2d1156e4635a5c30f60258c925142c59ad837c1b6708f1ff73
|
4
|
+
data.tar.gz: f27c94856df0db9d178537e8ac75598f8a355b338e725a80a5cb06a6e0ac610c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28b72e3f6a9950d3a95eb8d4f1c6a59f24a704ff63ac50384ffb2d22aa97c9f6b6e1f0c882a89cc6a0fd9ac22ea553a381514d56885f6f1cce41e7146153ab24
|
7
|
+
data.tar.gz: ac7c402d2b57a332ced9372a4546709d6b41a0fb082c823d292b87c8b11e4bf741047cbc10258f68acd228712f0ca974b6723246bd3ddc689920f656b1488974
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
-
##
|
3
|
+
## 1.0.0.rc1 (2020-06-10)
|
4
|
+
|
5
|
+
- Add `state_attr_accessor` for channels. ([@palkan][])
|
6
|
+
|
7
|
+
Just like `attr_accessor` but "persists" the state between RPC calls.
|
8
|
+
|
9
|
+
- Add `Channel#stop_stream_from` support. ([@palkan][])
|
10
|
+
|
11
|
+
- Add `RemoteConnections` support. ([@palkan][])
|
12
|
+
|
13
|
+
- Add `AnyCable::Rails.enabled?` method which returns true if Action Cable uses AnyCable adapter. ([@palkan][])
|
14
|
+
|
15
|
+
- Add `anycable:download` generator to download `anycable-go` binary. ([@palkan][])
|
4
16
|
|
5
17
|
- **Ruby 2.5+ is required**. ([@palkan][])
|
6
18
|
|
@@ -23,130 +35,7 @@ You must turn this feature on by setting `persistent_session_enabled: true` in t
|
|
23
35
|
|
24
36
|
- Add ability to develop the gem with Docker. ([@bibendi][])
|
25
37
|
|
26
|
-
|
27
|
-
|
28
|
-
- Fix Compatibility bug when using with AnyCable. ([@palkan][])
|
29
|
-
|
30
|
-
Compatibility patching (with `prepend` + `super`) conflicted with
|
31
|
-
the `ActionCable::Channel::Base` patching in the core functionality (which uses `alias`).
|
32
|
-
|
33
|
-
See [#95](https://github.com/anycable/anycable-rails/issues/95).
|
34
|
-
|
35
|
-
## 0.6.3 (2019-03-26)
|
36
|
-
|
37
|
-
- Fix connection factory reloading for development sake. ([@sponomarev][])
|
38
|
-
|
39
|
-
- Add `:anycable` subscription adapter alias. ([@sponomarev][])
|
40
|
-
|
41
|
-
- Don't set AnyCable connection factory for incompatible adapter ([@sponomarev][])
|
42
|
-
|
43
|
-
`anycable` server won't start with unpatched vanilla `ApplicationCable::Connection`.
|
44
|
-
|
45
|
-
Motivation in [#74](https://github.com/anycable/anycable-rails/issues/74).
|
46
|
-
|
47
|
-
- Fix instance detection inside complex cases in compatibility cops ([@sponomarev][])
|
48
|
-
|
49
|
-
## 0.6.2 (2019-01-10)
|
50
|
-
|
51
|
-
- Fixed `anycable` 0.6.1 compatibility. ([@palkan][])
|
52
|
-
|
53
|
-
- Broadcast logs to STDOUT in development only when server is running. ([@palkan][])
|
54
|
-
|
55
|
-
Fixes #59.
|
56
|
-
|
57
|
-
## 0.6.1 (2018-11-15)
|
58
|
-
|
59
|
-
- Fix regression introduced in [e64a366e](https://github.com/anycable/anycable-rails/commit/e64a366ea21293925e0c5c0b8e6595d65d5d0981#diff-fd0e56a6e825002eac978507c3581af7R14) ([@palkan][])
|
60
|
-
|
61
|
-
`Connection` patch could be loaded after `identify_by` is called, thus breaking
|
62
|
-
identifiers.
|
63
|
-
|
64
|
-
## 0.6.0 (2018-11-15)
|
65
|
-
|
66
|
-
**NOTE**: this version has been yanked from RubyGems due to the regression bug. Use 0.6.1.
|
67
|
-
|
68
|
-
- [PR #56](https://github.com/anycable/anycable-rails/pull/56) Request verification based on ActionCable config. ([@DmitryTsepelev][])
|
69
|
-
|
70
|
-
- Add WS server session ID to log tags if present. ([@palkan][])
|
71
|
-
|
72
|
-
- Support tagged logging. ([@palkan][])
|
73
|
-
|
74
|
-
- Action Cable monkey-patches are only loaded in the context of AnyCable CLI. ([@palkan][])
|
75
|
-
|
76
|
-
No need to think about `requie` and `group` for `anycable-rails`, just add it to Gemfile.
|
77
|
-
|
78
|
-
- Add `:any_cable` subscription adapter for Action Cable. ([@palkan][])
|
79
|
-
|
80
|
-
Use `:any_cable` adapter for Action Cable to broadcast data to AnyCable.
|
81
|
-
|
82
|
-
No more `pubsub` monkey-patches 🎉.
|
83
|
-
|
84
|
-
- Added Rails executor/reloader support. ([@palkan][])
|
85
|
-
|
86
|
-
- **[Breaking]** No more generators. ([@palkan][])
|
87
|
-
|
88
|
-
No need to generate AnyCable runner script since `anycable` gem ships with
|
89
|
-
the CLI.
|
90
|
-
|
91
|
-
- Add dynamic (`AnyCable::CompatibilityError`) compatibility checks. ([@DmitryTsepelev][])
|
92
|
-
|
93
|
-
- Added static (RuboCop) compatibility checks. ([@DmitryTsepelev][])
|
94
|
-
|
95
|
-
See https://github.com/anycable/anycable-rails/issues/52
|
96
|
-
|
97
|
-
## 0.5.4 (2018-06-13)
|
98
|
-
|
99
|
-
- Fix duplicate logs in development. ([@palkan][])
|
100
|
-
|
101
|
-
Fixes https://github.com/anycable/anycable_demo/issues/5.
|
102
|
-
|
103
|
-
## 0.5.3
|
104
|
-
|
105
|
-
- Fix return value of `Connection#handle_close`. ([@palkan][])
|
106
|
-
|
107
|
-
Should always be `true`, we do not expect a failure here.
|
108
|
-
|
109
|
-
## 0.5.2
|
110
|
-
|
111
|
-
- Add config/anycable.yml to Rails generator. ([@alekseyl][])
|
112
|
-
|
113
|
-
## 0.5.1
|
114
|
-
|
115
|
-
- Improve Rails integration. ([@palkan][])
|
116
|
-
|
117
|
-
Log to STDOUT in development.
|
118
|
-
Make order of initializers more deterministic.
|
119
|
-
Show warning if AnyCable is loaded after application initialization.
|
120
|
-
|
121
|
-
## 0.5.0
|
122
|
-
|
123
|
-
- [#17](https://github.com/anycable/anycable-rails/issues/17) Refactor logging. ([@palkan][])
|
124
|
-
|
125
|
-
Use Rails logger everywhere.
|
126
|
-
|
127
|
-
Add access logs ([anycable/anycable#20](https://github.com/anycable/anycable/issues/20)).
|
128
|
-
|
129
|
-
## 0.4.7
|
130
|
-
|
131
|
-
- Minor fixes. ([@palkan][])
|
132
|
-
|
133
|
-
## 0.4.6
|
134
|
-
|
135
|
-
- Disable mounting default Action Cable server when AnyCable is loaded. ([@palkan][])
|
136
|
-
|
137
|
-
## 0.4.5
|
138
|
-
|
139
|
-
- Handle tagged logger. ([@palkan][])
|
140
|
-
|
141
|
-
Ignore tagged logger features ('cause we do not have _persistent_ logger).
|
142
|
-
|
143
|
-
## 0.4.4
|
144
|
-
|
145
|
-
- Fix bug with ActiveRecord connections (https://github.com/anycable/anycable/issues/9). ([@palkan][])
|
146
|
-
|
147
|
-
## 0.4.0
|
148
|
-
|
149
|
-
- Initial version. ([@palkan][])
|
38
|
+
See [Changelog](https://github.com/anycable/anycable-rails/blob/0-6-stable/CHANGELOG.md) for versions <1.0.0.
|
150
39
|
|
151
40
|
[@palkan]: https://github.com/palkan
|
152
41
|
[@alekseyl]: https://github.com/alekseyl
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
[](https://gitpitch.com/anycable/anycable/master?grs=github)
|
1
|
+
[](https://gitpitch.com/anycable/anycable/master?grs=github)
|
2
|
+
[](https://rubygems.org/gems/anycable-rails)
|
3
|
+
[](https://github.com/anycable/anycable-rails/actions)
|
2
4
|
[](https://gitter.im/anycable/Lobby)
|
3
|
-
[](https://docs.anycable.io/#/ruby/rails)
|
5
|
+
[](https://docs.anycable.io/v1/#/ruby/rails)
|
4
6
|
|
5
7
|
# AnyCable Rails
|
6
8
|
|
@@ -10,10 +12,11 @@ With AnyCable you can use channels, client-side JS, broadcasting - (almost) all
|
|
10
12
|
|
11
13
|
You can even use Action Cable in development and not be afraid of [compatibility issues](#compatibility).
|
12
14
|
|
13
|
-
|
15
|
+
**Important** This is a readme for the upcoming v1.0 release. For v0.6.x see the readme from the [0-6-stable](https://github.com/anycable/anycable-rails/tree/0-6-stable) branch.
|
14
16
|
|
15
|
-
|
17
|
+
<!-- 💾 [Example Application](https://github.com/anycable/anycable_demo) -->
|
16
18
|
|
19
|
+
📑 [Documentation](https://docs.anycable.io/v1/#/ruby/rails).
|
17
20
|
|
18
21
|
<a href="https://evilmartians.com/">
|
19
22
|
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
@@ -21,12 +24,8 @@ You can even use Action Cable in development and not be afraid of [compatibility
|
|
21
24
|
## Requirements
|
22
25
|
|
23
26
|
- Ruby >= 2.5
|
24
|
-
- Rails >= 5.
|
25
|
-
- Redis (see [other options]() for broadcasting)
|
26
|
-
|
27
|
-
## How It Works?
|
28
|
-
|
29
|
-
<img src="https://trello-attachments.s3.amazonaws.com/5781e0ed48e4679e302833d3/820x987/5b6a305417b04e20e75f49c5816e027c/Anycable_vs_ActionCable_copy.jpg" width="400" />
|
27
|
+
- Rails >= 5.2
|
28
|
+
- Redis (see [other options](https://github.com/anycable/anycable/issues/2) for broadcasting)
|
30
29
|
|
31
30
|
## Usage
|
32
31
|
|
@@ -39,14 +38,12 @@ gem "anycable-rails"
|
|
39
38
|
gem "redis", ">= 4.0"
|
40
39
|
```
|
41
40
|
|
42
|
-
(and don't forget to run `bundle install`).
|
43
|
-
|
44
41
|
### Interactive set up
|
45
42
|
|
46
43
|
After the gem was installed, you can run an interactive wizard to configure your Rails application for using with AnyCable by running a generator:
|
47
44
|
|
48
45
|
```sh
|
49
|
-
|
46
|
+
bundle exec rails g anycable:setup
|
50
47
|
```
|
51
48
|
|
52
49
|
### Manual set up
|
@@ -86,38 +83,21 @@ $ bundle exec anycable
|
|
86
83
|
$ RAILS_ENV=production bundle exec anycable
|
87
84
|
```
|
88
85
|
|
89
|
-
And, finally, run AnyCable WebSocket server, e.g. [anycable-go](https://docs.anycable.io/#/anycable-go/getting_started):
|
86
|
+
And, finally, run AnyCable WebSocket server, e.g. [anycable-go](https://docs.anycable.io/v1/#/anycable-go/getting_started):
|
90
87
|
|
91
88
|
```sh
|
92
89
|
anycable-go --host=localhost --port=3334
|
93
90
|
```
|
94
91
|
|
95
|
-
See [documentation](https://docs.anycable.io/#/ruby/rails) for more information on AnyCable + Rails usage.
|
92
|
+
See [documentation](https://docs.anycable.io/v1/#/ruby/rails) for more information on AnyCable + Rails usage.
|
96
93
|
|
97
94
|
## Action Cable Compatibility
|
98
95
|
|
99
|
-
See [documentation](https://docs.anycable.io/#/ruby/compatibility).
|
100
|
-
|
101
|
-
## Links
|
102
|
-
|
103
|
-
- [AnyCable: Action Cable on steroids!](https://evilmartians.com/chronicles/anycable-actioncable-on-steroids)
|
104
|
-
|
105
|
-
- [From Action to Any](https://medium.com/@leshchuk/from-action-to-any-1e8d863dd4cf) by [@alekseyl](https://github.com/alekseyl)
|
106
|
-
|
107
|
-
## Talks
|
108
|
-
|
109
|
-
- One cable to rule them all, RubyKaigi 2018, [slides](https://speakerdeck.com/palkan/rubykaigi-2018-anycable-one-cable-to-rule-them-all) and [video](https://www.youtube.com/watch?v=jXCPuNICT8s) (EN)
|
110
|
-
|
111
|
-
- Wroc_Love.rb 2018 [slides](https://speakerdeck.com/palkan/wroc-love-dot-rb-2018-cables-cables-cables) and [video](https://www.youtube.com/watch?v=AUxFFOehiy0) (EN)
|
112
|
-
|
113
|
-
## Compatible WebSocket servers
|
114
|
-
|
115
|
-
- [AnyCable Go](https://github.com/anycable/anycable-go)
|
116
|
-
- [ErlyCable](https://github.com/anycable/erlycable)
|
96
|
+
See [documentation](https://docs.anycable.io/v1/#/ruby/compatibility).
|
117
97
|
|
118
98
|
## Contributing
|
119
99
|
|
120
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/anycable/anycable-rails.
|
100
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/anycable/anycable-rails](https://github.com/anycable/anycable-rails).
|
121
101
|
|
122
102
|
## Development
|
123
103
|
|
data/lib/anycable/rails.rb
CHANGED
@@ -5,6 +5,8 @@ require "anycable/rails/version"
|
|
5
5
|
require "anycable/rails/config"
|
6
6
|
require "anycable/rails/rack"
|
7
7
|
|
8
|
+
require "globalid"
|
9
|
+
|
8
10
|
module AnyCable
|
9
11
|
# Rails handler for AnyCable
|
10
12
|
module Rails
|
@@ -12,8 +14,40 @@ module AnyCable
|
|
12
14
|
|
13
15
|
ADAPTER_ALIASES = %w[any_cable anycable].freeze
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
class << self
|
18
|
+
def enabled?
|
19
|
+
adapter = ::ActionCable.server.config.cable&.fetch("adapter", nil)
|
20
|
+
compatible_adapter?(adapter)
|
21
|
+
end
|
22
|
+
|
23
|
+
def compatible_adapter?(adapter)
|
24
|
+
ADAPTER_ALIASES.include?(adapter)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Serialize connection/channel state variable to string
|
28
|
+
# using GlobalID where possible or JSON (if json: true)
|
29
|
+
def serialize(obj, json: false)
|
30
|
+
obj.try(:to_gid_param) || (json ? obj.to_json : obj)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Deserialize previously serialized value from string to
|
34
|
+
# Ruby object.
|
35
|
+
# If the resulting object is a Hash, make it indifferent
|
36
|
+
def deserialize(str, json: false)
|
37
|
+
str.yield_self do |val|
|
38
|
+
next unless val.is_a?(String)
|
39
|
+
|
40
|
+
gval = GlobalID::Locator.locate(val)
|
41
|
+
return gval if gval
|
42
|
+
|
43
|
+
next val unless json
|
44
|
+
|
45
|
+
JSON.parse(val)
|
46
|
+
end.yield_self do |val|
|
47
|
+
next val.with_indifferent_access if val.is_a?(Hash)
|
48
|
+
val
|
49
|
+
end
|
50
|
+
end
|
17
51
|
end
|
18
52
|
end
|
19
53
|
end
|
@@ -28,6 +28,10 @@ module ActionCable
|
|
28
28
|
connection.socket.subscribe identifier, broadcasting
|
29
29
|
end
|
30
30
|
|
31
|
+
def stop_stream_from(broadcasting)
|
32
|
+
connection.socket.unsubscribe identifier, broadcasting
|
33
|
+
end
|
34
|
+
|
31
35
|
def stop_all_streams
|
32
36
|
connection.socket.unsubscribe_from_all identifier
|
33
37
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "action_cable/connection"
|
4
|
+
require "anycable/rails/actioncable/connection/serializable_identification"
|
4
5
|
require "anycable/rails/refinements/subscriptions"
|
5
6
|
require "anycable/rails/actioncable/channel"
|
7
|
+
require "anycable/rails/actioncable/remote_connections"
|
6
8
|
require "anycable/rails/session_proxy"
|
7
9
|
|
8
10
|
module ActionCable
|
@@ -15,26 +17,26 @@ module ActionCable
|
|
15
17
|
|
16
18
|
using AnyCable::Refinements::Subscriptions
|
17
19
|
|
20
|
+
include SerializableIdentification
|
21
|
+
|
18
22
|
attr_reader :socket
|
19
23
|
|
20
24
|
delegate :env, :session, to: :request
|
21
25
|
|
22
26
|
class << self
|
23
27
|
def call(socket, **options)
|
24
|
-
new(socket, options)
|
28
|
+
new(socket, nil, options)
|
25
29
|
end
|
30
|
+
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
32
|
+
def initialize(socket, env, identifiers: "{}", subscriptions: [])
|
33
|
+
if env
|
34
|
+
# If env is set, then somehow we're in the context of Action Cable
|
35
|
+
# Return and print a warning in #process
|
36
|
+
@request = ActionDispatch::Request.new(env)
|
37
|
+
return
|
34
38
|
end
|
35
|
-
end
|
36
39
|
|
37
|
-
def initialize(socket, identifiers: "{}", subscriptions: [])
|
38
40
|
@ids = ActiveSupport::JSON.decode(identifiers)
|
39
41
|
|
40
42
|
@ltags = socket.cstate.read(LOG_TAGS_IDENTIFIER).yield_self do |raw_tags|
|
@@ -51,6 +53,18 @@ module ActionCable
|
|
51
53
|
subscriptions.each { |id| @subscriptions.fetch(id) }
|
52
54
|
end
|
53
55
|
|
56
|
+
def process
|
57
|
+
# Use Rails logger here to print to stdout in development
|
58
|
+
logger.error invalid_request_message
|
59
|
+
logger.info finished_request_message
|
60
|
+
[404, {"Content-Type" => "text/plain"}, ["Page not found"]]
|
61
|
+
end
|
62
|
+
|
63
|
+
def invalid_request_message
|
64
|
+
"You're trying to connect to Action Cable server while using AnyCable. " \
|
65
|
+
"See https://docs.anycable.io/v1/#/troubleshooting?id=server-raises-an-argumenterror-exception-when-client-tries-to-connect"
|
66
|
+
end
|
67
|
+
|
54
68
|
def handle_open
|
55
69
|
logger.info started_request_message if access_logs?
|
56
70
|
|
@@ -107,31 +121,6 @@ module ActionCable
|
|
107
121
|
socket.transmit encode(cable_message)
|
108
122
|
end
|
109
123
|
|
110
|
-
# Generate identifiers info.
|
111
|
-
# Converts GlobalID compatible vars to corresponding global IDs params.
|
112
|
-
def identifiers_hash
|
113
|
-
identifiers.each_with_object({}) do |id, acc|
|
114
|
-
obj = instance_variable_get("@#{id}")
|
115
|
-
next unless obj
|
116
|
-
|
117
|
-
acc[id] = obj.try(:to_gid_param) || obj
|
118
|
-
end.compact
|
119
|
-
end
|
120
|
-
|
121
|
-
def identifiers_json
|
122
|
-
identifiers_hash.to_json
|
123
|
-
end
|
124
|
-
|
125
|
-
# Fetch identifier and deserialize if neccessary
|
126
|
-
def fetch_identifier(name)
|
127
|
-
@cached_ids[name] ||= @cached_ids.fetch(name) do
|
128
|
-
val = ids[name.to_s]
|
129
|
-
next val unless val.is_a?(String)
|
130
|
-
|
131
|
-
GlobalID::Locator.locate(val) || val
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
124
|
def logger
|
136
125
|
@logger ||= TaggedLoggerProxy.new(AnyCable.logger, tags: ltags || [])
|
137
126
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionCable
|
4
|
+
module Connection
|
5
|
+
module SerializableIdentification
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class_methods do
|
9
|
+
def identified_by(*identifiers)
|
10
|
+
super
|
11
|
+
Array(identifiers).each do |identifier|
|
12
|
+
define_method(identifier) do
|
13
|
+
instance_variable_get(:"@#{identifier}") || fetch_identifier(identifier)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Generate identifiers info.
|
20
|
+
# Converts GlobalID compatible vars to corresponding global IDs params.
|
21
|
+
def identifiers_hash
|
22
|
+
identifiers.each_with_object({}) do |id, acc|
|
23
|
+
obj = instance_variable_get("@#{id}")
|
24
|
+
next unless obj
|
25
|
+
|
26
|
+
acc[id] = AnyCable::Rails.serialize(obj)
|
27
|
+
end.compact
|
28
|
+
end
|
29
|
+
|
30
|
+
def identifiers_json
|
31
|
+
identifiers_hash.to_json
|
32
|
+
end
|
33
|
+
|
34
|
+
# Fetch identifier and deserialize if neccessary
|
35
|
+
def fetch_identifier(name)
|
36
|
+
@cached_ids[name] ||= @cached_ids.fetch(name) do
|
37
|
+
AnyCable::Rails.deserialize(ids[name.to_s])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|