entangled 0.0.23 → 0.0.24

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d7c388678aa588a1f547b713feb70dbd9f5aaa44
4
- data.tar.gz: 5c4baa78c2e13abb9fdce0aabbd132698a474af4
3
+ metadata.gz: 1a88ff7623ddae9fbcfe0b93bc7080f309a48bf5
4
+ data.tar.gz: 179aa9cd196ea36f70ba8f4baf3d2d6cfc0c5dfe
5
5
  SHA512:
6
- metadata.gz: a740b57b3679899c1c3bde3d2b969f00a5457f826af461626119fdb4083a08eba5c5115b433fc8c243736a00a6c7c074fa9b8c8673c561fd2cf6c18cef72c134
7
- data.tar.gz: 17eb36090addf15cc12ea4a9c346dcb70411ac7273ce613ebfcf08143f9d47c15d0ee02ee8c1185a5b3200febabc2bb8fb13ac17538d205bb4a0b06daa0645e3
6
+ metadata.gz: 26935b60d39af34abfb60595102825d41a85188373bee4c5ac24b04392ceeb5ff8571f35229ef6ecb5432fca0626ac17286534256c3f4e9c9e5216cf4ad092e1
7
+ data.tar.gz: 2440601fc453c11adebee76f0c1bc061bfe74ad4d0c0b996d93b01f433e120d66bf916e528f447b54fd48d9da7e420bca46352a8f540bc4c15d9dc524b8477d4
data/README.md CHANGED
@@ -413,7 +413,8 @@ The gem relies heavily on convention over configuration and currently only works
413
413
  ## Development Priorities
414
414
  The following features are to be implemented next:
415
415
 
416
- - Support more than one `belongs_to` association in back end
416
+ - Check if routes really allow options right now. For example, what if I pass in shallow: true? Run rake routes to check!
417
+ - Allow for more than one level of nesting of `#channels` in `Entangled::Model`
417
418
  - Support `belongsTo` in front end
418
419
  - Support deeply nested `belongs_to`, e.g. `Parent > Child > Grandchild`
419
420
  - Support `has_one` association in back end and front end
@@ -430,6 +431,7 @@ The following features are to be implemented next:
430
431
  - Freeze destroyed object
431
432
  - Set `$persisted()` to false on a destroyed object
432
433
  - Add `.destroyAll()` function to `Resources`
434
+ - Add support for plain JavaScript usage (without Angular) and add section about that to Readme
433
435
 
434
436
  ## Contributing
435
437
  1. [Fork it](https://github.com/dchacke/entangled/fork) - you will notice that the repo comes with a back end and a front end part to test both parts of the gem
@@ -73,59 +73,54 @@ module Entangled
73
73
  attributes.merge(errors: errors).as_json
74
74
  end
75
75
 
76
- # The channel name for a single record containing the
77
- # inferred channel name from the class and the record's
78
- # id. For example, if it's a DeliciousTaco with the id 1,
79
- # the member channel for the single record is "delicious_tacos/1".
80
- # Nesting is automatically applied through the use of
81
- # the collection channel.
76
+ # Build channels. Channels always at least include
77
+ # a collection channel, i.e. /tacos, and a member
78
+ # channel, i.e. /tacos/1, for direct access.
82
79
  #
83
- # The member channel has to be the same as the path to
84
- # the resource's show action, including a leading
85
- # forward slash
86
- def member_channel
87
- "#{collection_channel}/#{self.to_param}"
88
- end
80
+ # If the model belongs_to other models, two nested
81
+ # channels are added for each belongs_to association.
82
+ # E.g., if child belongs_to parent, the two channels
83
+ # that are added are parents/1/children, and
84
+ # parents/1/children/1, leaving a total of four channels
85
+ def channels
86
+ channels = []
87
+ plural_name = self.class.name.underscore.pluralize
89
88
 
90
- # The inferred channel name for the collection. For example,
91
- # if the class name is DeliciousTaco, the collection channel
92
- # is "delicious_tacos".
93
- #
94
- # If the model belongs to another model, the channel is nested
95
- # accordingly. For example, if a child belongs to a parent,
96
- # the child's collection channel is "parents/1/children".
97
- #
98
- # The collection channel has to be the same as the path to
99
- # the resource's index action, including a leading forward slash
100
- def collection_channel
101
- belongs_to_assocations = self.class.reflect_on_all_associations(:belongs_to)
102
- own_channel = self.class.name.underscore.pluralize
103
-
104
- if belongs_to_assocations.any?
105
- parent = send(belongs_to_assocations.first.name)
106
- "#{parent.member_channel}/#{own_channel}"
107
- else
108
- "/#{own_channel}"
89
+ # Add collection's channel
90
+ channels << "/#{plural_name}"
91
+
92
+ # Add member's channel
93
+ channels << "/#{plural_name}/#{to_param}"
94
+
95
+ # Find parent names from belongs_to associations
96
+ parents = self.class.reflect_on_all_associations(:belongs_to)
97
+
98
+ # Add nested channels for each parent
99
+ parents.map(&:name).each do |parent_name|
100
+ # Get parent record from name
101
+ parent = send(parent_name)
102
+
103
+ # Get parent class's plural underscore name
104
+ parent_plural_name = parent_name.to_s.underscore.pluralize
105
+
106
+ # Add collection's channel nested under parent's member channel
107
+ channels << "/#{parent_plural_name}/#{parent.to_param}/#{plural_name}"
108
+
109
+ # Add member's channel nested under parent's member channel
110
+ channels << "/#{parent_plural_name}/#{parent.to_param}/#{plural_name}/#{to_param}"
109
111
  end
112
+
113
+ channels
110
114
  end
111
115
 
112
116
  private
113
117
 
114
118
  # Publishes to client. Whoever is subscribed
115
- # to the model's channel or the record's channel
116
- # gets the message
119
+ # to the model's channels gets the message
117
120
  def publish(action)
118
- # Publish to model's channel
119
- redis.publish(
120
- collection_channel,
121
- json(action)
122
- )
123
-
124
- # Publish to record#s channel
125
- redis.publish(
126
- member_channel,
127
- json(action)
128
- )
121
+ channels.each do |channel|
122
+ redis.publish(channel, json(action))
123
+ end
129
124
  end
130
125
 
131
126
  # JSON containing the type of action (:create, :update
@@ -1,3 +1,3 @@
1
1
  module Entangled
2
- VERSION = "0.0.23"
2
+ VERSION = "0.0.24"
3
3
  end
@@ -14,21 +14,15 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
14
14
  it 'publishes creation' do
15
15
  redis = stub_redis
16
16
 
17
- # Publishing to collection channel
18
- expect(redis).to have_received(:publish).with(
19
- foo.collection_channel, {
20
- action: :create,
21
- resource: foo
22
- }.to_json
23
- )
24
-
25
- # Publishing to member channel
26
- expect(redis).to have_received(:publish).with(
27
- foo.member_channel, {
28
- action: :create,
29
- resource: foo
30
- }.to_json
31
- )
17
+ # Publishing to channels
18
+ foo.channels.each do |channel|
19
+ expect(redis).to have_received(:publish).with(
20
+ channel, {
21
+ action: :create,
22
+ resource: foo
23
+ }.to_json
24
+ )
25
+ end
32
26
  end
33
27
 
34
28
  it 'does not publish update' do
@@ -36,19 +30,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
36
30
 
37
31
  foo.update(body: 'bar')
38
32
 
39
- expect(redis).to have_received(:publish).with(
40
- 'foos', {
41
- action: :update,
42
- resource: foo
43
- }.to_json
44
- ).never
45
-
46
- expect(redis).to have_received(:publish).with(
47
- foo.member_channel, {
48
- action: :update,
49
- resource: foo
50
- }.to_json
51
- ).never
33
+ foo.channels.each do |channel|
34
+ expect(redis).to have_received(:publish).with(
35
+ channel, {
36
+ action: :update,
37
+ resource: foo
38
+ }.to_json
39
+ ).never
40
+ end
52
41
  end
53
42
 
54
43
  it 'does not publish destruction' do
@@ -56,19 +45,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
56
45
 
57
46
  foo.destroy
58
47
 
59
- expect(redis).to have_received(:publish).with(
60
- 'foos', {
61
- action: :destroy,
62
- resource: foo
63
- }.to_json
64
- ).never
65
-
66
- expect(redis).to have_received(:publish).with(
67
- foo.member_channel, {
68
- action: :destroy,
69
- resource: foo
70
- }.to_json
71
- ).never
48
+ foo.channels.each do |channel|
49
+ expect(redis).to have_received(:publish).with(
50
+ channel, {
51
+ action: :destroy,
52
+ resource: foo
53
+ }.to_json
54
+ ).never
55
+ end
72
56
  end
73
57
  end
74
58
 
@@ -79,20 +63,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
79
63
  redis = stub_redis
80
64
 
81
65
  # Publishing to collection channel
82
- expect(redis).to have_received(:publish).with(
83
- bar.collection_channel, {
84
- action: :create,
85
- resource: bar
86
- }.to_json
87
- )
88
-
89
- # Publishing to member channel
90
- expect(redis).to have_received(:publish).with(
91
- bar.member_channel, {
92
- action: :create,
93
- resource: bar
94
- }.to_json
95
- )
66
+ bar.channels.each do |channel|
67
+ expect(redis).to have_received(:publish).with(
68
+ channel, {
69
+ action: :create,
70
+ resource: bar
71
+ }.to_json
72
+ )
73
+ end
96
74
  end
97
75
 
98
76
  it 'publishes the update' do
@@ -100,19 +78,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
100
78
 
101
79
  bar.update(body: 'bar')
102
80
 
103
- expect(redis).to have_received(:publish).with(
104
- bar.collection_channel, {
105
- action: :update,
106
- resource: bar
107
- }.to_json
108
- )
109
-
110
- expect(redis).to have_received(:publish).with(
111
- bar.member_channel, {
112
- action: :update,
113
- resource: bar
114
- }.to_json
115
- )
81
+ bar.channels.each do |channel|
82
+ expect(redis).to have_received(:publish).with(
83
+ channel, {
84
+ action: :update,
85
+ resource: bar
86
+ }.to_json
87
+ )
88
+ end
116
89
  end
117
90
 
118
91
  it 'does not publish destruction' do
@@ -120,19 +93,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
120
93
 
121
94
  bar.destroy
122
95
 
123
- expect(redis).to have_received(:publish).with(
124
- bar.collection_channel, {
125
- action: :destroy,
126
- resource: bar
127
- }.to_json
128
- ).never
129
-
130
- expect(redis).to have_received(:publish).with(
131
- bar.member_channel, {
132
- action: :destroy,
133
- resource: bar
134
- }.to_json
135
- ).never
96
+ bar.channels.each do |channel|
97
+ expect(redis).to have_received(:publish).with(
98
+ channel, {
99
+ action: :destroy,
100
+ resource: bar
101
+ }.to_json
102
+ ).never
103
+ end
136
104
  end
137
105
  end
138
106
 
@@ -142,21 +110,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
142
110
  it 'does not publish the creation' do
143
111
  redis = stub_redis
144
112
 
145
- # Publishing to collection channel
146
- expect(redis).to have_received(:publish).with(
147
- foobar.collection_channel, {
148
- action: :create,
149
- resource: foobar
150
- }.to_json
151
- ).never
152
-
153
- # Publishing to member channel
154
- expect(redis).to have_received(:publish).with(
155
- foobar.member_channel, {
156
- action: :create,
157
- resource: foobar
158
- }.to_json
159
- ).never
113
+ foobar.channels.each do |channel|
114
+ expect(redis).to have_received(:publish).with(
115
+ channel, {
116
+ action: :create,
117
+ resource: foobar
118
+ }.to_json
119
+ ).never
120
+ end
160
121
  end
161
122
 
162
123
  it 'publishes the update' do
@@ -164,19 +125,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
164
125
 
165
126
  foobar.update(body: 'foobar')
166
127
 
167
- expect(redis).to have_received(:publish).with(
168
- foobar.collection_channel, {
169
- action: :update,
170
- resource: foobar
171
- }.to_json
172
- )
173
-
174
- expect(redis).to have_received(:publish).with(
175
- foobar.member_channel, {
176
- action: :update,
177
- resource: foobar
178
- }.to_json
179
- )
128
+ foobar.channels.each do |channel|
129
+ expect(redis).to have_received(:publish).with(
130
+ channel, {
131
+ action: :update,
132
+ resource: foobar
133
+ }.to_json
134
+ )
135
+ end
180
136
  end
181
137
 
182
138
  it 'publishes the destruction' do
@@ -184,19 +140,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
184
140
 
185
141
  foobar.destroy
186
142
 
187
- expect(redis).to have_received(:publish).with(
188
- foobar.collection_channel, {
189
- action: :destroy,
190
- resource: foobar
191
- }.to_json
192
- )
193
-
194
- expect(redis).to have_received(:publish).with(
195
- foobar.member_channel, {
196
- action: :destroy,
197
- resource: foobar
198
- }.to_json
199
- )
143
+ foobar.channels.each do |channel|
144
+ expect(redis).to have_received(:publish).with(
145
+ channel, {
146
+ action: :destroy,
147
+ resource: foobar
148
+ }.to_json
149
+ )
150
+ end
200
151
  end
201
152
  end
202
153
 
@@ -206,21 +157,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
206
157
  it 'publishes the creation' do
207
158
  redis = stub_redis
208
159
 
209
- # Publishing to collection channel
210
- expect(redis).to have_received(:publish).with(
211
- barfoo.collection_channel, {
212
- action: :create,
213
- resource: barfoo
214
- }.to_json
215
- )
216
-
217
- # Publishing to member channel
218
- expect(redis).to have_received(:publish).with(
219
- barfoo.member_channel, {
220
- action: :create,
221
- resource: barfoo
222
- }.to_json
223
- )
160
+ barfoo.channels.each do |channel|
161
+ expect(redis).to have_received(:publish).with(
162
+ channel, {
163
+ action: :create,
164
+ resource: barfoo
165
+ }.to_json
166
+ )
167
+ end
224
168
  end
225
169
 
226
170
  it 'dpes not publish the update' do
@@ -228,19 +172,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
228
172
 
229
173
  barfoo.update(body: 'barfoo')
230
174
 
231
- expect(redis).to have_received(:publish).with(
232
- barfoo.collection_channel, {
233
- action: :update,
234
- resource: barfoo
235
- }.to_json
236
- ).never
237
-
238
- expect(redis).to have_received(:publish).with(
239
- barfoo.member_channel, {
240
- action: :update,
241
- resource: barfoo
242
- }.to_json
243
- ).never
175
+ barfoo.channels.each do |channel|
176
+ expect(redis).to have_received(:publish).with(
177
+ channel, {
178
+ action: :update,
179
+ resource: barfoo
180
+ }.to_json
181
+ ).never
182
+ end
244
183
  end
245
184
 
246
185
  it 'does not publish the destruction' do
@@ -248,19 +187,14 @@ RSpec.describe 'Inclusion/exclusion', type: :model do
248
187
 
249
188
  barfoo.destroy
250
189
 
251
- expect(redis).to have_received(:publish).with(
252
- barfoo.collection_channel, {
253
- action: :destroy,
254
- resource: barfoo
255
- }.to_json
256
- ).never
257
-
258
- expect(redis).to have_received(:publish).with(
259
- barfoo.member_channel, {
260
- action: :destroy,
261
- resource: barfoo
262
- }.to_json
263
- ).never
190
+ barfoo.channels.each do |channel|
191
+ expect(redis).to have_received(:publish).with(
192
+ channel, {
193
+ action: :destroy,
194
+ resource: barfoo
195
+ }.to_json
196
+ ).never
197
+ end
264
198
  end
265
199
  end
266
200
  end
@@ -21,15 +21,25 @@ RSpec.describe Item, type: :model do
21
21
  let(:list) { List.create(name: 'foo') }
22
22
  let(:item) { list.items.create(name: 'bar') }
23
23
 
24
- describe '#member_channel' do
25
- it 'has a nested member channel' do
26
- expect(item.member_channel).to eq "/lists/#{list.to_param}/items/#{item.to_param}"
24
+ describe '#channels' do
25
+ it 'is an array of channels' do
26
+ expect(item.channels).to be_an Array
27
+ end
28
+
29
+ it "includes the collection's channel" do
30
+ expect(item.channels).to include '/items'
31
+ end
32
+
33
+ it "includes the item's direct channel" do
34
+ expect(item.channels).to include "/items/#{item.to_param}"
35
+ end
36
+
37
+ it "includes the collection's nested channel" do
38
+ expect(item.channels).to include "/lists/#{list.to_param}/items"
27
39
  end
28
- end
29
40
 
30
- describe '#collection_channel' do
31
- it 'has a nested collection channel' do
32
- expect(item.collection_channel).to eq "/lists/#{list.to_param}/items"
41
+ it "includes the item's nested channel" do
42
+ expect(item.channels).to include "/lists/#{list.to_param}/items/#{item.to_param}"
33
43
  end
34
44
  end
35
45
  end
@@ -16,15 +16,17 @@ RSpec.describe List, type: :model do
16
16
  describe 'Methods' do
17
17
  let(:list) { List.create(name: 'foo') }
18
18
 
19
- describe '#member_channel' do
20
- it 'has the right channel' do
21
- expect(list.member_channel).to eq "/lists/#{list.to_param}"
19
+ describe '#channels' do
20
+ it 'is an array of channels' do
21
+ expect(list.channels).to be_an Array
22
+ end
23
+
24
+ it "includes the collection's channel" do
25
+ expect(list.channels).to include '/lists'
22
26
  end
23
- end
24
27
 
25
- describe '#collection_channel' do
26
- it 'has the right channel' do
27
- expect(list.collection_channel).to eq '/lists'
28
+ it "includes the member's channel" do
29
+ expect(list.channels).to include "/lists/#{list.to_param}"
28
30
  end
29
31
  end
30
32
  end
@@ -43,23 +45,27 @@ RSpec.describe List, type: :model do
43
45
  it 'broadcasts the creation to the collection channel' do
44
46
  redis = stub_redis
45
47
 
46
- expect(redis).to have_received(:publish).with(
47
- list.collection_channel, {
48
- action: :create,
49
- resource: list
50
- }.to_json
51
- )
48
+ list.channels.each do |channel|
49
+ expect(redis).to have_received(:publish).with(
50
+ channel, {
51
+ action: :create,
52
+ resource: list
53
+ }.to_json
54
+ )
55
+ end
52
56
  end
53
57
 
54
58
  it 'broadcasts the creation to the member channel' do
55
59
  redis = stub_redis
56
60
 
57
- expect(redis).to have_received(:publish).with(
58
- list.member_channel, {
59
- action: :create,
60
- resource: list
61
- }.to_json
62
- )
61
+ list.channels.each do |channel|
62
+ expect(redis).to have_received(:publish).with(
63
+ channel, {
64
+ action: :create,
65
+ resource: list
66
+ }.to_json
67
+ )
68
+ end
63
69
  end
64
70
  end
65
71
 
@@ -71,12 +77,14 @@ RSpec.describe List, type: :model do
71
77
 
72
78
  list.update(name: 'bar')
73
79
 
74
- expect(redis).to have_received(:publish).with(
75
- list.collection_channel, {
76
- action: :update,
77
- resource: list
78
- }.to_json
79
- )
80
+ list.channels.each do |channel|
81
+ expect(redis).to have_received(:publish).with(
82
+ channel, {
83
+ action: :update,
84
+ resource: list
85
+ }.to_json
86
+ )
87
+ end
80
88
  end
81
89
 
82
90
  it 'broadcasts the update to the member channel' do
@@ -84,12 +92,14 @@ RSpec.describe List, type: :model do
84
92
 
85
93
  list.update(name: 'bar')
86
94
 
87
- expect(redis).to have_received(:publish).with(
88
- list.member_channel, {
89
- action: :update,
90
- resource: list
91
- }.to_json
92
- )
95
+ list.channels.each do |channel|
96
+ expect(redis).to have_received(:publish).with(
97
+ channel, {
98
+ action: :update,
99
+ resource: list
100
+ }.to_json
101
+ )
102
+ end
93
103
  end
94
104
  end
95
105
 
@@ -101,12 +111,14 @@ RSpec.describe List, type: :model do
101
111
 
102
112
  list.destroy
103
113
 
104
- expect(redis).to have_received(:publish).with(
105
- list.collection_channel, {
106
- action: :destroy,
107
- resource: list
108
- }.to_json
109
- )
114
+ list.channels.each do |channel|
115
+ expect(redis).to have_received(:publish).with(
116
+ channel, {
117
+ action: :destroy,
118
+ resource: list
119
+ }.to_json
120
+ )
121
+ end
110
122
  end
111
123
 
112
124
  it 'broadcasts the destruction to the member channel' do
@@ -114,12 +126,14 @@ RSpec.describe List, type: :model do
114
126
 
115
127
  list.destroy
116
128
 
117
- expect(redis).to have_received(:publish).with(
118
- list.member_channel, {
119
- action: :destroy,
120
- resource: list
121
- }.to_json
122
- )
129
+ list.channels.each do |channel|
130
+ expect(redis).to have_received(:publish).with(
131
+ channel, {
132
+ action: :destroy,
133
+ resource: list
134
+ }.to_json
135
+ )
136
+ end
123
137
  end
124
138
  end
125
139
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entangled
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.23
4
+ version: 0.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dennis Charles Hackethal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-16 00:00:00.000000000 Z
11
+ date: 2015-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler