live_record 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/jrpolidario/live_record.svg?branch=master)](https://travis-ci.org/jrpolidario/live_record)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/live_record.svg)](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
|