live_record 0.2.2 → 0.2.3
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 +39 -9
- data/app/assets/javascripts/live_record/helpers/case_converter.coffee +16 -0
- data/app/assets/javascripts/live_record/helpers/load_records.coffee +3 -3
- data/app/assets/javascripts/live_record/model/create.coffee +35 -5
- data/lib/live_record/generators/templates/javascript.coffee.rb +10 -3
- data/lib/live_record/version.rb +1 -1
- data/spec/factories/posts.rb +1 -0
- data/spec/factories/users.rb +5 -0
- data/spec/features/live_record_syncing_spec.rb +39 -4
- data/spec/internal/app/assets/javascripts/posts.coffee +3 -0
- data/spec/internal/app/assets/javascripts/users.coffee +11 -0
- data/spec/internal/app/controllers/users_controller.rb +75 -0
- data/spec/internal/app/models/post.rb +2 -1
- data/spec/internal/app/models/user.rb +12 -0
- data/spec/internal/app/views/posts/_post.json.jbuilder +1 -1
- data/spec/internal/app/views/posts/index.html.erb +1 -0
- data/spec/internal/app/views/users/_user.json.jbuilder +2 -0
- data/spec/internal/app/views/users/index.json.jbuilder +1 -0
- data/spec/internal/config/routes.rb +1 -0
- data/spec/internal/db/schema.rb +8 -0
- data/spec/rails_helper.rb +2 -2
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cb6c6112e8dc95504592f04bbcc692184625232
|
4
|
+
data.tar.gz: 8fc5c877c5bc1b14f84c7e4d835880cf057c62e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4f90c7c3dcd0be1ab798a484d87af59d0fda7383c22f1568c5cf9ec0bae8c6cef13d915fa3884ed72d13e30c85128bcb978e4f1c57cd423551087a042a8f944
|
7
|
+
data.tar.gz: 6fbb76854c2369cb1432b4f5dd1989e4880d16cc41707233be861999c5fbf1838cc4c23cf2d3791aca74cfe05424d773056aeafbb2e7fccb82f5e864055294a6
|
data/README.md
CHANGED
@@ -15,8 +15,8 @@
|
|
15
15
|
|
16
16
|
## Requirements
|
17
17
|
|
18
|
-
*
|
19
|
-
*
|
18
|
+
* **Ruby >= 2.2.2**
|
19
|
+
* **Rails >= 5.0, < 5.2**
|
20
20
|
|
21
21
|
## Demo
|
22
22
|
|
@@ -114,7 +114,7 @@
|
|
114
114
|
1. Add the following to your `Gemfile`:
|
115
115
|
|
116
116
|
```ruby
|
117
|
-
gem 'live_record', '~> 0.2.
|
117
|
+
gem 'live_record', '~> 0.2.3'
|
118
118
|
```
|
119
119
|
|
120
120
|
2. Run:
|
@@ -212,13 +212,23 @@
|
|
212
212
|
)
|
213
213
|
```
|
214
214
|
|
215
|
-
### Example 2 - Model + Callbacks
|
215
|
+
### Example 2 - Model + Callbacks + Associations
|
216
216
|
|
217
217
|
```js
|
218
218
|
// app/assets/javascripts/books.js
|
219
219
|
LiveRecord.Model.create(
|
220
220
|
{
|
221
221
|
modelName: 'Book',
|
222
|
+
belongsTo: {
|
223
|
+
// allows you to do `bookInstance.user()` and `bookInstance.library()`
|
224
|
+
user: { foreignKey: 'user_id', modelName: 'User' },
|
225
|
+
library: { foreignKey: 'library_id', modelName: 'Library' }
|
226
|
+
},
|
227
|
+
hasMany: {
|
228
|
+
// allows you to do `bookInstance.pages()` and `bookInstance.bookReviews()`
|
229
|
+
pages: { foreignKey: 'book_id', modelName: 'Page' },
|
230
|
+
bookReviews: { foreignKey: 'book_id', modelName: 'Review' }
|
231
|
+
},
|
222
232
|
callbacks: {
|
223
233
|
'on:connect': [
|
224
234
|
function() {
|
@@ -238,7 +248,7 @@
|
|
238
248
|
#### Model Callbacks supported:
|
239
249
|
* `on:connect`
|
240
250
|
* `on:disconnect`
|
241
|
-
* `on:
|
251
|
+
* `on:responseError`
|
242
252
|
* `before:create`
|
243
253
|
* `after:create`
|
244
254
|
* `before:update`
|
@@ -248,7 +258,7 @@
|
|
248
258
|
|
249
259
|
> Each callback should map to an array of functions
|
250
260
|
|
251
|
-
* `on:
|
261
|
+
* `on:responseError` supports a function argument: The "Error Code". i.e.
|
252
262
|
|
253
263
|
### Example 3 - Handling Response Error
|
254
264
|
|
@@ -257,7 +267,7 @@
|
|
257
267
|
{
|
258
268
|
modelName: 'Book',
|
259
269
|
callbacks: {
|
260
|
-
'on:
|
270
|
+
'on:responseError': [
|
261
271
|
function(errorCode) {
|
262
272
|
console.log(errorCode); // errorCode is a string, representing the type of error. See Response Error Codes below:
|
263
273
|
}
|
@@ -451,10 +461,18 @@
|
|
451
461
|
### `LiveRecord.Model.create(CONFIG)`
|
452
462
|
* `CONFIG` (Object)
|
453
463
|
* `modelName`: (String, Required)
|
464
|
+
* `belongsTo`: (Object)
|
465
|
+
* `ASSOCIATIONNAME`: (Object)
|
466
|
+
* `foreignKey`: (String)
|
467
|
+
* `modelName`: (String)
|
468
|
+
* `hasMany`: (Object)
|
469
|
+
* `ASSOCIATIONNAME`: (Object)
|
470
|
+
* `foreignKey`: (String)
|
471
|
+
* `modelName`: (String)
|
454
472
|
* `callbacks`: (Object)
|
455
473
|
* `on:connect`: (Array of functions)
|
456
474
|
* `on:disconnect`: (Array of functions)
|
457
|
-
* `on:
|
475
|
+
* `on:responseError`: (Array of functions; function argument = ERROR_CODE (String))
|
458
476
|
* `before:create`: (Array of functions)
|
459
477
|
* `after:create`: (Array of functions)
|
460
478
|
* `before:update`: (Array of functions)
|
@@ -464,6 +482,7 @@
|
|
464
482
|
* `plugins`: (Object)
|
465
483
|
* `LiveDOM`: (Boolean)
|
466
484
|
* creates a `MODEL` and stores it into `LiveRecord.Model.all` array
|
485
|
+
* `hasMany` and `belongsTo` `modelName` above should be a valid defined `LiveRecord.Model`
|
467
486
|
* returns the newly created `MODEL`
|
468
487
|
|
469
488
|
### `MODEL.all`
|
@@ -512,6 +531,11 @@
|
|
512
531
|
### `MODELINSTANCE.ATTRIBUTENAME()`
|
513
532
|
* returns the attribute value of corresponding to `ATTRIBUTENAME`. (i.e. `bookInstance.id()`, `bookInstance.created_at()`)
|
514
533
|
|
534
|
+
### `MODELINSTANCE.ASSOCIATIONAME()`
|
535
|
+
* if association is "has many", then returns an array of associated records (if any exists in current store)
|
536
|
+
* if association is "belongs to", then returns the record (if exists in current store)
|
537
|
+
* (i.e. `bookInstance.user()`, `bookInstance.reviews()`)
|
538
|
+
|
515
539
|
### `MODELINSTANCE.subscribe()`
|
516
540
|
* 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.
|
517
541
|
* returns the `subscription` object (the ActionCable subscription object itself)
|
@@ -572,10 +596,16 @@
|
|
572
596
|
* MIT
|
573
597
|
|
574
598
|
## Changelog
|
599
|
+
* 0.2.3
|
600
|
+
* IMPORTANT! renamed callback from `on:response_error` to `on:responseError` for conformity. So please update your code accordingly.
|
601
|
+
* added [associations](#example-2---model--callbacks--associations):
|
602
|
+
* `hasMany` which allows you to do `bookInstance.reviews()`
|
603
|
+
* `belongsTo` which allows you to do `bookInstance.user()`
|
604
|
+
* fixed `loadRecords()` throwing an error when there is no response
|
575
605
|
* 0.2.2
|
576
606
|
* minor fix: "new records" subscription: `.modelName` was not being referenced properly, but should have not affected any functionalities.
|
577
607
|
* 0.2.1
|
578
|
-
* you can now access what attributes have changed; see [`
|
608
|
+
* you can now access what attributes have changed; see [`MODELINSTANCE.changes`](#modelinstancechanges) above.
|
579
609
|
* 0.2.0
|
580
610
|
* Ability to subscribe to new records (supports lost connection auto-restreaming)
|
581
611
|
* See [9th step of Setup above](#setup)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# ref: https://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
|
2
|
+
|
3
|
+
LiveRecord.helpers.caseConverter =
|
4
|
+
toCamel: (string) ->
|
5
|
+
string.replace(
|
6
|
+
/(\-[a-z])/g,
|
7
|
+
($1) ->
|
8
|
+
$1.toUpperCase().replace('-','')
|
9
|
+
)
|
10
|
+
|
11
|
+
toUnderscore: (string) ->
|
12
|
+
string.replace(
|
13
|
+
/([A-Z])/g,
|
14
|
+
($1) ->
|
15
|
+
"_"+$1.toLowerCase()
|
16
|
+
)
|
@@ -7,7 +7,7 @@ LiveRecord.helpers.loadRecords = (args) ->
|
|
7
7
|
$.getJSON(
|
8
8
|
args['url']
|
9
9
|
).done(
|
10
|
-
(data) ->
|
10
|
+
(data) ->
|
11
11
|
record_or_records = undefined
|
12
12
|
|
13
13
|
# Array JSON
|
@@ -23,7 +23,7 @@ LiveRecord.helpers.loadRecords = (args) ->
|
|
23
23
|
record_or_records = records
|
24
24
|
|
25
25
|
# Single-Record JSON
|
26
|
-
else
|
26
|
+
else if data
|
27
27
|
record_attributes = data
|
28
28
|
record = new LiveRecord.Model.all[args['modelName']](record_attributes)
|
29
29
|
record.create()
|
@@ -34,4 +34,4 @@ LiveRecord.helpers.loadRecords = (args) ->
|
|
34
34
|
).fail(
|
35
35
|
(jqxhr, textStatus, error) ->
|
36
36
|
args['onError'].call(this, jqxhr, textStatus, error) if args['onError']
|
37
|
-
)
|
37
|
+
)
|
@@ -15,13 +15,43 @@ LiveRecord.Model.create = (config) ->
|
|
15
15
|
|
16
16
|
Model.modelName = config.modelName
|
17
17
|
|
18
|
+
Model.associations =
|
19
|
+
hasMany: config.hasMany
|
20
|
+
belongsTo: config.belongsTo
|
21
|
+
|
22
|
+
# getting has_many association records
|
23
|
+
for associationName, associationConfig of Model.associations.hasMany
|
24
|
+
Model.prototype[associationName] = ->
|
25
|
+
self = this
|
26
|
+
associatedModel = LiveRecord.Model.all[associationConfig.modelName]
|
27
|
+
throw new Error('No defined model for "' + associationConfig.modelName + '"') unless associatedModel
|
28
|
+
|
29
|
+
# TODO: speed up searching for associated records, or use cache-maps
|
30
|
+
associatedRecords = []
|
31
|
+
|
32
|
+
for id, record of associatedModel.all
|
33
|
+
isAssociated = record[associationConfig.foreignKey]() == self.id()
|
34
|
+
associatedRecords.push(record) if isAssociated
|
35
|
+
|
36
|
+
associatedRecords
|
37
|
+
|
38
|
+
# getting belongs_to association record
|
39
|
+
for associationName, associationConfig of Model.associations.belongsTo
|
40
|
+
Model.prototype[associationName] = ->
|
41
|
+
self = this
|
42
|
+
associatedModel = LiveRecord.Model.all[associationConfig.modelName]
|
43
|
+
throw new Error('No defined model for "' + associationConfig.modelName + '"') unless associatedModel
|
44
|
+
|
45
|
+
belongsToID = self[associationConfig.foreignKey]()
|
46
|
+
associatedModel.all[belongsToID]
|
47
|
+
|
18
48
|
Model.all = {}
|
19
49
|
|
20
50
|
Model.subscriptions = []
|
21
51
|
|
22
52
|
Model.subscribe = (config) ->
|
23
|
-
config
|
24
|
-
config.callbacks
|
53
|
+
config ||= {}
|
54
|
+
config.callbacks ||= {}
|
25
55
|
|
26
56
|
subscription = App.cable.subscriptions.create(
|
27
57
|
{
|
@@ -110,7 +140,7 @@ LiveRecord.Model.create = (config) ->
|
|
110
140
|
if data.error
|
111
141
|
@record()._staleSince = (new Date()).toISOString() unless @record()._staleSince
|
112
142
|
@onError[data.error.code].call(this, data)
|
113
|
-
@record()._callCallbacks('on:
|
143
|
+
@record()._callCallbacks('on:responseError', [data.error.code])
|
114
144
|
delete @record()['subscription']
|
115
145
|
else
|
116
146
|
@onAction[data.action].call(this, data)
|
@@ -198,7 +228,7 @@ LiveRecord.Model.create = (config) ->
|
|
198
228
|
Model._callbacks = {
|
199
229
|
'on:connect': [],
|
200
230
|
'on:disconnect': [],
|
201
|
-
'on:
|
231
|
+
'on:responseError': [],
|
202
232
|
'before:create': [],
|
203
233
|
'after:create': [],
|
204
234
|
'before:update': [],
|
@@ -210,7 +240,7 @@ LiveRecord.Model.create = (config) ->
|
|
210
240
|
Model.prototype._callbacks = {
|
211
241
|
'on:connect': [],
|
212
242
|
'on:disconnect': [],
|
213
|
-
'on:
|
243
|
+
'on:responseError': [],
|
214
244
|
'before:create': [],
|
215
245
|
'after:create': [],
|
216
246
|
'before:update': [],
|
@@ -3,14 +3,21 @@ LiveRecord.Model.create(
|
|
3
3
|
{
|
4
4
|
modelName: '<%= singular_table_name.camelcase %>',
|
5
5
|
plugins: {
|
6
|
+
# remove this line if you're not using LiveDOM
|
6
7
|
LiveDOM: true
|
7
8
|
},
|
8
|
-
|
9
|
-
|
9
|
+
|
10
|
+
## More configurations below. See https://github.com/jrpolidario/live_record#example-1---model
|
11
|
+
# belongsTo: {
|
12
|
+
# user: { foreignKey: 'user_id', modelName: 'User' }
|
13
|
+
# },
|
14
|
+
# hasMany: {
|
15
|
+
# books: { foreignKey: '<%= singular_table_name %>_id', modelName: 'Book' }
|
16
|
+
# },
|
10
17
|
# callbacks: {
|
11
18
|
# 'on:disconnect': [],
|
12
19
|
# 'after:update': [],
|
13
20
|
# }
|
14
21
|
}
|
15
22
|
)
|
16
|
-
<% end -%>
|
23
|
+
<% end -%>
|
data/lib/live_record/version.rb
CHANGED
data/spec/factories/posts.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'rails_helper'
|
2
2
|
|
3
3
|
RSpec.feature 'LiveRecord Syncing', type: :feature do
|
4
|
-
let(:
|
5
|
-
let(:
|
6
|
-
let(:
|
4
|
+
let(:user1) { create(:user) }
|
5
|
+
let(:user2) { create(:user) }
|
6
|
+
let(:post1) { create(:post, user: user1) }
|
7
|
+
let(:post2) { create(:post, user: user1) }
|
8
|
+
let(:post3) { create(:post, user: nil) }
|
9
|
+
let!(:users) { [user1, user2] }
|
7
10
|
let!(:posts) { [post1, post2, post3] }
|
8
11
|
|
9
12
|
scenario 'User sees live changes (updates) of post records', js: true do
|
@@ -59,6 +62,38 @@ RSpec.feature 'LiveRecord Syncing', type: :feature do
|
|
59
62
|
expect(post3_content_td).to_not have_content('post3newcontent')
|
60
63
|
end
|
61
64
|
|
65
|
+
scenario 'JS-Client can access Model associations record objects in its current store', js: true do
|
66
|
+
visit '/posts'
|
67
|
+
|
68
|
+
# let's wait for all records first before checking correct associations
|
69
|
+
wait before: -> { evaluate_script('Object.keys( LiveRecord.Model.all.User.all ).length') }, becomes: -> (value) { value == users.size }, duration: 10.seconds
|
70
|
+
expect(evaluate_script('Object.keys( LiveRecord.Model.all.User.all ).length')).to eq users.size
|
71
|
+
wait before: -> { evaluate_script('Object.keys( LiveRecord.Model.all.Post.all ).length') }, becomes: -> (value) { value == posts.size }, duration: 10.seconds
|
72
|
+
expect(evaluate_script('Object.keys( LiveRecord.Model.all.Post.all ).length')).to eq posts.size
|
73
|
+
|
74
|
+
# users should have correct associated posts
|
75
|
+
expect(evaluate_script(
|
76
|
+
<<-eos
|
77
|
+
LiveRecord.Model.all.User.all[#{user1.id}].posts().map(
|
78
|
+
function(post) { return post.id() }
|
79
|
+
)
|
80
|
+
eos
|
81
|
+
)).to eq user1.posts.pluck(:id)
|
82
|
+
|
83
|
+
expect(evaluate_script(
|
84
|
+
<<-eos
|
85
|
+
LiveRecord.Model.all.User.all[#{user2.id}].posts().map(
|
86
|
+
function(post) { return post.id() }
|
87
|
+
)
|
88
|
+
eos
|
89
|
+
)).to eq user2.posts.pluck(:id)
|
90
|
+
|
91
|
+
# posts should belong to correct associated user
|
92
|
+
expect(evaluate_script("LiveRecord.Model.all.Post.all[#{post1.id}].user().id()")).to eq post1.user.id
|
93
|
+
expect(evaluate_script("LiveRecord.Model.all.Post.all[#{post2.id}].user().id()")).to eq post2.user.id
|
94
|
+
expect(evaluate_script("LiveRecord.Model.all.Post.all[#{post3.id}].user()")).to eq nil
|
95
|
+
end
|
96
|
+
|
62
97
|
# see spec/internal/app/views/posts/index.html.erb to see the subscribe "conditions"
|
63
98
|
scenario 'JS-Client receives live new (create) post records where specified "conditions" matched', js: true do
|
64
99
|
visit '/posts'
|
@@ -89,7 +124,7 @@ RSpec.feature 'LiveRecord Syncing', type: :feature do
|
|
89
124
|
|
90
125
|
wait before: -> { evaluate_script("LiveRecord.Model.all.Post.all[#{post4.id}] == undefined") }, becomes: -> (value) { value == false }
|
91
126
|
expect(evaluate_script("LiveRecord.Model.all.Post.all[#{post4.id}] == undefined")).to be false
|
92
|
-
|
127
|
+
|
93
128
|
wait before: -> { evaluate_script("LiveRecord.Model.all.Post.all[#{post5.id}] == undefined") }, becomes: -> (value) { value == false }
|
94
129
|
expect(evaluate_script("LiveRecord.Model.all.Post.all[#{post5.id}] == undefined")).to be false
|
95
130
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class UsersController < ApplicationController
|
2
|
+
before_action :set_user, only: [:show, :edit, :update, :destroy]
|
3
|
+
|
4
|
+
# GET /users
|
5
|
+
# GET /users.json
|
6
|
+
def index
|
7
|
+
request.session['init'] = true if request.session.id.nil?
|
8
|
+
@users = User.all
|
9
|
+
end
|
10
|
+
|
11
|
+
# GET /users/1
|
12
|
+
# GET /users/1.json
|
13
|
+
def show
|
14
|
+
end
|
15
|
+
|
16
|
+
# GET /users/new
|
17
|
+
def new
|
18
|
+
@user = User.new
|
19
|
+
end
|
20
|
+
|
21
|
+
# GET /users/1/edit
|
22
|
+
def edit
|
23
|
+
end
|
24
|
+
|
25
|
+
# POST /users
|
26
|
+
# POST /users.json
|
27
|
+
def create
|
28
|
+
@user = User.new(user_params)
|
29
|
+
|
30
|
+
respond_to do |format|
|
31
|
+
if @user.save
|
32
|
+
format.html { redirect_to @user, notice: 'User was successfully created.' }
|
33
|
+
format.json { render :show, status: :created, location: @user }
|
34
|
+
else
|
35
|
+
format.html { render :new }
|
36
|
+
format.json { render json: @user.errors, status: :unprocessable_entity }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# PATCH/PUT /users/1
|
42
|
+
# PATCH/PUT /users/1.json
|
43
|
+
def update
|
44
|
+
respond_to do |format|
|
45
|
+
if @user.update(user_params)
|
46
|
+
format.html { redirect_to @user, notice: 'User was successfully updated.' }
|
47
|
+
format.json { render :show, status: :ok, location: @user }
|
48
|
+
else
|
49
|
+
format.html { render :edit }
|
50
|
+
format.json { render json: @user.errors, status: :unprocessable_entity }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# DELETE /users/1
|
56
|
+
# DELETE /users/1.json
|
57
|
+
def destroy
|
58
|
+
@user.destroy
|
59
|
+
respond_to do |format|
|
60
|
+
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
|
61
|
+
format.json { head :no_content }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
# Use callbacks to share common setup or constraints between actions.
|
67
|
+
def set_user
|
68
|
+
@user = User.find(params[:id])
|
69
|
+
end
|
70
|
+
|
71
|
+
# Never trust parameters from the scary internet, only allow the white list through.
|
72
|
+
def user_params
|
73
|
+
params.require(:user).permit(:email)
|
74
|
+
end
|
75
|
+
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
class Post < ApplicationRecord
|
2
2
|
include LiveRecord::Model::Callbacks
|
3
3
|
|
4
|
+
belongs_to :user
|
4
5
|
has_many :live_record_updates, as: :recordable, dependent: :destroy
|
5
6
|
|
6
7
|
def self.live_record_whitelisted_attributes(post, current_user)
|
7
8
|
# Add attributes to this array that you would like current_user to have access to.
|
8
9
|
# Defaults to empty array, thereby blocking everything by default, only unless explicitly stated here so.
|
9
|
-
[:title, :is_enabled, :created_at, :updated_at]
|
10
|
+
[:title, :is_enabled, :user_id, :created_at, :updated_at]
|
10
11
|
end
|
11
12
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class User < ApplicationRecord
|
2
|
+
include LiveRecord::Model::Callbacks
|
3
|
+
|
4
|
+
has_many :live_record_updates, as: :recordable, dependent: :destroy
|
5
|
+
has_many :posts
|
6
|
+
|
7
|
+
def self.live_record_whitelisted_attributes(user, current_user)
|
8
|
+
# Add attributes to this array that you would like current_user to have access to.
|
9
|
+
# Defaults to empty array, thereby blocking everything by default, only unless explicitly stated here so.
|
10
|
+
[:email, :created_at, :updated_at]
|
11
|
+
end
|
12
|
+
end
|
@@ -1,2 +1,2 @@
|
|
1
|
-
json.extract! post, :id, :title, :content, :created_at, :updated_at
|
1
|
+
json.extract! post, :id, :title, :content, :user_id, :created_at, :updated_at
|
2
2
|
json.url post_url(post, format: :json)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
<script>
|
2
2
|
LiveRecord.helpers.loadRecords({ modelName: 'Post' });
|
3
|
+
LiveRecord.helpers.loadRecords({ modelName: 'User', url: '<%= j users_path %>' });
|
3
4
|
LiveRecord.Model.all.Post.subscribe({ where: { is_enabled_eq: true, content_eq: 'somecontent' }});
|
4
5
|
</script>
|
5
6
|
<p id="notice"><%= notice %></p>
|
@@ -0,0 +1 @@
|
|
1
|
+
json.array! @users, partial: 'users/user', as: :user
|
data/spec/internal/db/schema.rb
CHANGED
@@ -11,8 +11,16 @@ ActiveRecord::Schema.define do
|
|
11
11
|
t.string "title"
|
12
12
|
t.text "content"
|
13
13
|
t.boolean "is_enabled"
|
14
|
+
t.integer "user_id"
|
14
15
|
t.datetime "created_at", null: false
|
15
16
|
t.datetime "updated_at", null: false
|
16
17
|
t.index ["is_enabled"], name: "index_posts_on_is_enabled"
|
18
|
+
t.index ["user_id"], name: "index_posts_on_user_id"
|
19
|
+
end
|
20
|
+
|
21
|
+
create_table "users", force: :cascade do |t|
|
22
|
+
t.string "email"
|
23
|
+
t.datetime "created_at", null: false
|
24
|
+
t.datetime "updated_at", null: false
|
17
25
|
end
|
18
26
|
end
|
data/spec/rails_helper.rb
CHANGED
@@ -4,7 +4,7 @@ Dir[__dir__ + '/helpers/*.rb'].each {|file| require file }
|
|
4
4
|
|
5
5
|
ActiveRecord::Migration.maintain_test_schema!
|
6
6
|
|
7
|
-
Capybara.javascript_driver = :selenium_chrome_headless # :selenium_chrome
|
7
|
+
Capybara.javascript_driver = :selenium_chrome_headless # :selenium_chrome
|
8
8
|
Capybara.server = :puma
|
9
9
|
|
10
10
|
RSpec.configure do |config|
|
@@ -23,7 +23,7 @@ RSpec.configure do |config|
|
|
23
23
|
DatabaseCleaner.clean
|
24
24
|
DatabaseCleaner.strategy = :deletion
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
config.before(:each) do
|
28
28
|
DatabaseCleaner.start
|
29
29
|
DatabaseCleaner.clean
|
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.3
|
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-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -272,6 +272,7 @@ files:
|
|
272
272
|
- Rakefile
|
273
273
|
- app/assets/javascripts/live_record.coffee
|
274
274
|
- app/assets/javascripts/live_record/helpers.coffee
|
275
|
+
- app/assets/javascripts/live_record/helpers/case_converter.coffee
|
275
276
|
- app/assets/javascripts/live_record/helpers/load_records.coffee
|
276
277
|
- app/assets/javascripts/live_record/helpers/spaceship.coffee
|
277
278
|
- app/assets/javascripts/live_record/model.coffee
|
@@ -301,19 +302,23 @@ files:
|
|
301
302
|
- lib/live_record/version.rb
|
302
303
|
- live_record.gemspec
|
303
304
|
- spec/factories/posts.rb
|
305
|
+
- spec/factories/users.rb
|
304
306
|
- spec/features/live_record_syncing_spec.rb
|
305
307
|
- spec/helpers/wait.rb
|
306
308
|
- spec/internal/app/assets/config/manifest.js
|
307
309
|
- spec/internal/app/assets/javascripts/application.js
|
308
310
|
- spec/internal/app/assets/javascripts/cable.js
|
309
311
|
- spec/internal/app/assets/javascripts/posts.coffee
|
312
|
+
- spec/internal/app/assets/javascripts/users.coffee
|
310
313
|
- spec/internal/app/channels/application_cable/channel.rb
|
311
314
|
- spec/internal/app/channels/application_cable/connection.rb
|
312
315
|
- spec/internal/app/controllers/application_controller.rb
|
313
316
|
- spec/internal/app/controllers/posts_controller.rb
|
317
|
+
- spec/internal/app/controllers/users_controller.rb
|
314
318
|
- spec/internal/app/models/application_record.rb
|
315
319
|
- spec/internal/app/models/live_record_update.rb
|
316
320
|
- spec/internal/app/models/post.rb
|
321
|
+
- spec/internal/app/models/user.rb
|
317
322
|
- spec/internal/app/views/layouts/application.html.erb
|
318
323
|
- spec/internal/app/views/posts/_form.html.erb
|
319
324
|
- spec/internal/app/views/posts/_post.json.jbuilder
|
@@ -323,6 +328,8 @@ files:
|
|
323
328
|
- spec/internal/app/views/posts/new.html.erb
|
324
329
|
- spec/internal/app/views/posts/show.html.erb
|
325
330
|
- spec/internal/app/views/posts/show.json.jbuilder
|
331
|
+
- spec/internal/app/views/users/_user.json.jbuilder
|
332
|
+
- spec/internal/app/views/users/index.json.jbuilder
|
326
333
|
- spec/internal/config/cable.yml
|
327
334
|
- spec/internal/config/database.yml
|
328
335
|
- spec/internal/config/routes.rb
|