live_record 0.2.0 → 0.2.1
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/README.md +36 -21
- data/app/assets/javascripts/live_record/model/create.coffee +12 -2
- data/lib/live_record/version.rb +1 -1
- data/spec/features/live_record_syncing_spec.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2a60a5fbaf627b89846d36f65ea5a685b766d3c
|
4
|
+
data.tar.gz: e617a00065338ef2d909b3de3e7ec16782e611e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4952880f039e019e7721b83e1d4b77618de2d37c5d80cf133b7c714df5d293d9a4e85120e89a0a63193d59188d2c99b3aec7a558c271dfb1919b3c0c90426cd3
|
7
|
+
data.tar.gz: f9550bc5a31b21c9999d5a53c63a74608eea74e0619fe696c68c127142bc28c7576b2052121ce25111cf4139dc76fa61c35904898f2eacae0720c6c7e95f7b18
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
[](https://travis-ci.org/jrpolidario/live_record)
|
2
|
+
[](https://badge.fury.io/rb/live_record)
|
2
3
|
|
3
4
|
## About
|
4
5
|
|
@@ -25,7 +26,7 @@
|
|
25
26
|
|
26
27
|
* say we have a `Book` model which has the following attributes:
|
27
28
|
* `title:string`
|
28
|
-
* `author:
|
29
|
+
* `author:string`
|
29
30
|
* `is_enabled:boolean`
|
30
31
|
* on the JS client-side:
|
31
32
|
|
@@ -60,27 +61,27 @@
|
|
60
61
|
// the store is accessible through
|
61
62
|
LiveRecord.Model.all.Book.all;
|
62
63
|
|
63
|
-
// all records in the JS store are automatically subscribed to the backend
|
64
|
-
|
65
|
-
// because the `book` above is already created in the store, you'll notice that it should automatically sync itself including all other possible whitelisted attributes
|
66
|
-
console.log(book.attributes);
|
67
|
-
// at this point then, console.log above will show the following on your browser console:
|
68
|
-
// {id: 1, title: 'Harry Potter', author: 'J.K. Rowling', is_enabled: true, created_at: '2017-08-02T12:39:49.238Z', updated_at: '2017-08-02T12:39:49.238Z'}
|
64
|
+
// all records in the JS store are automatically subscribed to the backend LiveRecord::ChangesChannel, which meant syncing (update / destroy) changes from the backend
|
69
65
|
|
70
66
|
// All attributes automatically updates itself so you'll be sure that the following line (for example) is always up-to-date
|
71
67
|
console.log(book.updated_at())
|
72
68
|
|
73
69
|
// you can also add a callback that will be invoked whenever the Book object has been updated (see all supported callbacks further below)
|
70
|
+
// i.e. you might want to update DOM elements when the attributes have changed
|
74
71
|
book.addCallback('after:update', function() {
|
75
|
-
// let's say you update the DOM elements here when the attributes have changed
|
76
72
|
// `this` refers to the Book record that has been updated
|
77
|
-
|
73
|
+
|
74
|
+
console.log(this.attributes);
|
75
|
+
// this book record should have been updated with all other possible whitelisted attributes even if you just initally passed in only the ID; thus console.log above would output below
|
76
|
+
// {id: 1, title: 'Harry Potter', author: 'J.K. Rowling', is_enabled: true, created_at: '2017-08-02T12:39:49.238Z', updated_at: '2017-08-02T12:39:49.238Z'}
|
77
|
+
|
78
|
+
console.log(this.changes)
|
79
|
+
// from above, you can also access what has changed, and would have an example output below
|
80
|
+
// {title: ['Harry Potter', 'New Title'], updated_at: ['2017-08-02T12:39:49.238Z', 2017-08-02T13:00:00.047Z]}
|
78
81
|
});
|
79
82
|
|
80
83
|
// or you can add a Model-wide callback that will be invoked whenever ANY Book object has been updated
|
81
84
|
LiveRecord.Model.all.Book.addCallback('after:update', function() {
|
82
|
-
// let's say you update the DOM elements here when the attributes have changed
|
83
|
-
// `this` refers to the Book record that has been updated
|
84
85
|
console.log(this);
|
85
86
|
})
|
86
87
|
```
|
@@ -91,6 +92,7 @@
|
|
91
92
|
# app/models/book.rb
|
92
93
|
class Book < ApplicationRecord
|
93
94
|
include LiveRecord::Model::Callbacks
|
95
|
+
has_many :live_record_updates, as: :recordable, dependent: :destroy
|
94
96
|
|
95
97
|
def self.live_record_whitelisted_attributes(book, current_user)
|
96
98
|
# Add attributes to this array that you would like `current_user` to have access to when syncing this particular `book`
|
@@ -112,7 +114,7 @@
|
|
112
114
|
1. Add the following to your `Gemfile`:
|
113
115
|
|
114
116
|
```ruby
|
115
|
-
gem 'live_record', '~> 0.2.
|
117
|
+
gem 'live_record', '~> 0.2.1'
|
116
118
|
```
|
117
119
|
|
118
120
|
2. Run:
|
@@ -160,6 +162,7 @@
|
|
160
162
|
# app/models/book.rb (example 1)
|
161
163
|
class Book < ApplicationRecord
|
162
164
|
include LiveRecord::Model::Callbacks
|
165
|
+
has_many :live_record_updates, as: :recordable, dependent: :destroy
|
163
166
|
|
164
167
|
def self.live_record_whitelisted_attributes(book, current_user)
|
165
168
|
# Add attributes to this array that you would like current_user to have access to when syncing.
|
@@ -175,6 +178,7 @@
|
|
175
178
|
# app/models/book.rb (example 1)
|
176
179
|
class Book < ApplicationRecord
|
177
180
|
include LiveRecord::Model::Callbacks
|
181
|
+
has_many :live_record_updates, as: :recordable, dependent: :destroy
|
178
182
|
|
179
183
|
def self.live_record_whitelisted_attributes(book, current_user)
|
180
184
|
# Notice that from above, you also have access to `book` (the record currently requested by the client to be synced),
|
@@ -369,7 +373,7 @@
|
|
369
373
|
# app/models/book.rb
|
370
374
|
class Book < ApplicationRecord
|
371
375
|
include LiveRecord::Model::Callbacks
|
372
|
-
has_many :live_record_updates, as: :recordable
|
376
|
+
has_many :live_record_updates, as: :recordable, dependent: :destroy
|
373
377
|
|
374
378
|
def self.live_record_whitelisted_attributes(book, current_user)
|
375
379
|
[:title, :is_enabled]
|
@@ -438,6 +442,9 @@
|
|
438
442
|
|
439
443
|
## JS API
|
440
444
|
|
445
|
+
### `LiveRecord.Model.all`
|
446
|
+
* Object of which properties are the models
|
447
|
+
|
441
448
|
### `LiveRecord.Model.create(CONFIG)`
|
442
449
|
* `CONFIG` (Object)
|
443
450
|
* `modelName`: (String, Required)
|
@@ -456,7 +463,10 @@
|
|
456
463
|
* creates a `MODEL` and stores it into `LiveRecord.Model.all` array
|
457
464
|
* returns the newly created `MODEL`
|
458
465
|
|
459
|
-
### `MODEL
|
466
|
+
### `MODEL.all`
|
467
|
+
* Object of which properties are IDs of the records
|
468
|
+
|
469
|
+
### `MODEL.subscribe(CONFIG)`
|
460
470
|
* `CONFIG` (Object, Optional)
|
461
471
|
* `where`: (Object)
|
462
472
|
* `ATTRIBUTENAME_OPERATOR`: (Any Type)
|
@@ -465,7 +475,7 @@
|
|
465
475
|
* `on:disconnect`: (function Object)
|
466
476
|
* `before:create`: (function Object)
|
467
477
|
* `after:create`: (function Object)
|
468
|
-
* subscribes to the `PublicationsChannel`, which then automatically receives new records from the backend.
|
478
|
+
* subscribes to the `LiveRecord::PublicationsChannel`, which then automatically receives new records from the backend.
|
469
479
|
* you can also pass in `callbacks` (see above). These callbacks is only applicable to this subscription, and is independent of the Model and Instance callbacks.
|
470
480
|
* `ATTRIBUTENAME_OPERATOR` means something like (for example): `is_enabled_eq`, where `is_enabled` is the `ATTRIBUTENAME` and `eq` is the `OPERATOR`.
|
471
481
|
* you can have as many `ATTRIBUTENAME_OPERATOR` as you like, but keep in mind that the logic applied to them is "AND", and not "OR". For "OR" conditions, use `ransack`
|
@@ -483,8 +493,8 @@
|
|
483
493
|
* `in` in Array; i.e. `id_in: [2, 56, 19, 68]`
|
484
494
|
* `not_in` in Array; i.e. `id_not_in: [2, 56, 19, 68]`
|
485
495
|
|
486
|
-
### `MODEL
|
487
|
-
* unsubscribes to the `PublicationsChannel`, thereby will not be receiving new records anymore.
|
496
|
+
### `MODEL.unsubscribe(SUBSCRIPTION)`
|
497
|
+
* unsubscribes to the `LiveRecord::PublicationsChannel`, thereby will not be receiving new records anymore.
|
488
498
|
|
489
499
|
### `new LiveRecord.Model.all.MODELNAME(ATTRIBUTES)`
|
490
500
|
* `ATTRIBUTES` (Object)
|
@@ -500,11 +510,11 @@
|
|
500
510
|
* returns the attribute value of corresponding to `ATTRIBUTENAME`. (i.e. `bookInstance.id()`, `bookInstance.created_at()`)
|
501
511
|
|
502
512
|
### `MODELINSTANCE.subscribe()`
|
503
|
-
* subscribes to the `
|
513
|
+
* subscribes to the `LiveRecord::ChangesChannel`. This instance should already be subscribed by default after being stored, unless there is a `on:response_error` or manually `unsubscribed()` which then you should manually call this `subscribe()` function after correctly handling the response error, or whenever desired.
|
504
514
|
* returns the `subscription` object (the ActionCable subscription object itself)
|
505
515
|
|
506
516
|
### `MODELINSTANCE.unsubscribe()`
|
507
|
-
* unsubscribes to the `
|
517
|
+
* unsubscribes to the `LiveRecord::ChangesChannel`, thereby will not be receiving changes (updates/destroy) anymore.
|
508
518
|
|
509
519
|
### `MODELINSTANCE.isSubscribed()`
|
510
520
|
* returns `true` or `false` accordingly if the instance is subscribed
|
@@ -513,7 +523,7 @@
|
|
513
523
|
* the `subscription` object (the ActionCable subscription object itself)
|
514
524
|
|
515
525
|
### `MODELINSTANCE.create()`
|
516
|
-
* stores the instance to the store, and then `subscribe()` to the `
|
526
|
+
* stores the instance to the store, and then `subscribe()` to the `LiveRecord::ChangesChannel` for syncing
|
517
527
|
* returns the instance
|
518
528
|
|
519
529
|
### `MODELINSTANCE.update(ATTRIBUTES)`
|
@@ -525,6 +535,11 @@
|
|
525
535
|
* removes the instance from the store, and then `unsubscribe()`
|
526
536
|
* returns the instance
|
527
537
|
|
538
|
+
### `MODELINSTANCE.changes`
|
539
|
+
* you can **ONLY** access this inside the function callback for `before:update` and `after:update`, and is automatically cleared after
|
540
|
+
* returns an object having the same format as [Rails's own `changes`](https://apidock.com/rails/ActiveModel/Dirty/changes)
|
541
|
+
* i.e. `{title: ['Harry Potter', 'New Title'], updated_at: ['2017-08-02T12:39:49.238Z', 2017-08-02T13:00:00.047Z]}`
|
542
|
+
|
528
543
|
### `MODELINSTANCE.addCallback(CALLBACKKEY, CALLBACKFUNCTION)`
|
529
544
|
* `CALLBACKKEY` (String) see supported callbacks above
|
530
545
|
* `CALLBACKFUNCTION` (function Object)
|
@@ -537,7 +552,7 @@
|
|
537
552
|
|
538
553
|
## FAQ
|
539
554
|
* How to remove the view templates being overriden by LiveRecord when generating a controller or scaffold?
|
540
|
-
* amongst other things, `rails generate live_record:install` will override the default scaffold view templates: **show.html.erb** and **index.html.erb**; to revert back, just simply delete the following files (though you'll need to manually update or regenerate the view files that were already generated prior to deleting
|
555
|
+
* amongst other things, `rails generate live_record:install` will override the default scaffold view templates: **show.html.erb** and **index.html.erb**; to revert back, just simply delete the following files (though you'll need to manually update or regenerate the view files that were already generated prior to deleting the following files):
|
541
556
|
* **lib/templates/erb/scaffold/index.html.erb**
|
542
557
|
* **lib/templates/erb/scaffold/show.html.erb**
|
543
558
|
|
@@ -14,8 +14,6 @@ LiveRecord.Model.create = (config) ->
|
|
14
14
|
this
|
15
15
|
|
16
16
|
Model.modelName = config.modelName
|
17
|
-
|
18
|
-
Model.store = {}
|
19
17
|
|
20
18
|
Model.all = {}
|
21
19
|
|
@@ -120,7 +118,9 @@ LiveRecord.Model.create = (config) ->
|
|
120
118
|
# handler for received() callback above
|
121
119
|
onAction:
|
122
120
|
update: (data) ->
|
121
|
+
@record()._setChangesFrom(data.attributes)
|
123
122
|
@record().update(data.attributes)
|
123
|
+
@record()._unsetChanges()
|
124
124
|
|
125
125
|
destroy: (data) ->
|
126
126
|
@record().destroy()
|
@@ -242,6 +242,16 @@ LiveRecord.Model.create = (config) ->
|
|
242
242
|
for callback in this._callbacks[callbackKey]
|
243
243
|
callback.apply(this, args)
|
244
244
|
|
245
|
+
Model.prototype._setChangesFrom = (attributes) ->
|
246
|
+
this.changes = {}
|
247
|
+
|
248
|
+
for attributeName, attributeValue of attributes
|
249
|
+
unless this.attributes[attributeName] && this.attributes[attributeName] == attributeValue
|
250
|
+
this.changes[attributeName] = [this.attributes[attributeName], attributeValue]
|
251
|
+
|
252
|
+
Model.prototype._unsetChanges = () ->
|
253
|
+
delete this['changes']
|
254
|
+
|
245
255
|
# AFTER MODEL INITIALISATION
|
246
256
|
|
247
257
|
# add callbacks from arguments
|
data/lib/live_record/version.rb
CHANGED
@@ -122,7 +122,7 @@ RSpec.feature 'LiveRecord Syncing', type: :feature do
|
|
122
122
|
Thread.new do
|
123
123
|
sleep(2)
|
124
124
|
|
125
|
-
# temporarily stop all current
|
125
|
+
# temporarily stop all current changes_channel connections
|
126
126
|
ObjectSpace.each_object(LiveRecord::ChangesChannel) do |changes_channel|
|
127
127
|
changes_channel.connection.close
|
128
128
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: live_record
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jules Roman B. Polidario
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|