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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68e46da08f168efb9e1ebfb51f075548aaaa42cd
4
- data.tar.gz: fbb81c2b262d59fa5b05e7a8b1a84bb20962538f
3
+ metadata.gz: e2a60a5fbaf627b89846d36f65ea5a685b766d3c
4
+ data.tar.gz: e617a00065338ef2d909b3de3e7ec16782e611e8
5
5
  SHA512:
6
- metadata.gz: 2c3a0ffcac47a14e301671222403391380ece8577cf2a62ec1477b604155a31fb660b5fcc2e3106ebf2e94245c77e38b32aaf83d7c5e0d24ca1617fdd19370e3
7
- data.tar.gz: 95949617075641208bbf35ace36222c43f4d11bb415110ea1da45ef05281191b28dc80e4136dadf9ff71f6f4f4836ae14b102403ae2e53973e49fbdae5992338
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:text`
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 LiveRecordChannel, which meant syncing (update / destroy) changes from 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
- console.log(this);
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.0'
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`.subscribe(CONFIG)
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`.unsubscribe(SUBSCRIPTION)
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 `LiveRecordChannel`. 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.
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 `LiveRecordChannel`, thereby will not be receiving changes (updates/destroy) anymore.
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 `LiveRecordChannel` for syncing
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 to the following files):
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
@@ -1,3 +1,3 @@
1
1
  module LiveRecord
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.2.1'.freeze
3
3
  end
@@ -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 publication_channel connections
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.0
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-12 00:00:00.000000000 Z
11
+ date: 2017-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails