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 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