hyper-mesh 0.5.0 → 0.5.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 +21 -13
- data/docs/action_cable_quickstart.md +9 -7
- data/docs/activerecord_api.md +73 -0
- data/docs/client_side_scoping.md +5 -5
- data/docs/configuration_details.md +11 -0
- data/docs/pusher_faker_quickstart.md +95 -6
- data/docs/pusher_quickstart.md +96 -8
- data/docs/simple_poller_quickstart.md +21 -55
- data/docs/todo-example.md +2 -0
- data/docs/words-example.md +3 -0
- data/examples/action-cable/Gemfile +7 -8
- data/examples/action-cable/Gemfile.lock +28 -46
- data/examples/{simple-poller/app/assets/javascripts/channels → action-cable/app/assets/images}/.keep +0 -0
- data/examples/action-cable/app/assets/javascripts/application.js +5 -3
- data/examples/action-cable/app/assets/javascripts/cable.js +13 -0
- data/examples/{simple-poller/app/controllers/concerns → action-cable/app/assets/javascripts/channels}/.keep +0 -0
- data/examples/{simple-poller → action-cable}/app/channels/application_cable/channel.rb +0 -0
- data/examples/{simple-poller → action-cable}/app/channels/application_cable/connection.rb +0 -0
- data/examples/action-cable/app/controllers/test_controller.rb +0 -1
- data/examples/{simple-poller/app/models/concerns → action-cable/app/models/public}/.keep +0 -0
- data/examples/action-cable/app/policies/application_policy.rb +9 -1
- data/examples/action-cable/app/views/components.rb +2 -3
- data/examples/action-cable/bin/spring +4 -3
- data/examples/action-cable/config/application.rb +1 -11
- data/examples/action-cable/config/environments/development.rb +12 -1
- data/examples/action-cable/config/initializers/hyper_mesh.rb +4 -0
- data/examples/action-cable/config/routes.rb +1 -1
- data/examples/action-cable/config/secrets.yml +2 -2
- data/examples/action-cable/db/migrate/{20160921223808_create_words.rb → 20161114213840_create_words.rb} +0 -0
- data/examples/action-cable/db/schema.rb +14 -1
- data/examples/action-cable/db/seeds.rb +7 -0
- data/examples/{simple-poller/app/views/components → action-cable/lib/assets}/.keep +0 -0
- data/examples/action-cable/lib/tasks/.keep +0 -0
- data/examples/action-cable/test/controllers/.keep +0 -0
- data/examples/action-cable/test/fixtures/.keep +0 -0
- data/examples/action-cable/test/fixtures/files/.keep +0 -0
- data/examples/action-cable/test/fixtures/words.yml +7 -0
- data/examples/action-cable/test/helpers/.keep +0 -0
- data/examples/action-cable/test/integration/.keep +0 -0
- data/examples/action-cable/test/mailers/.keep +0 -0
- data/examples/action-cable/test/models/.keep +0 -0
- data/examples/action-cable/test/models/word_test.rb +7 -0
- data/examples/action-cable/test/test_helper.rb +10 -0
- data/examples/pusher-fake/.gitignore +21 -0
- data/examples/pusher-fake/Gemfile +59 -0
- data/examples/pusher-fake/Gemfile.lock +262 -0
- data/examples/pusher-fake/README.md +24 -0
- data/examples/pusher-fake/Rakefile +6 -0
- data/examples/pusher-fake/app/assets/config/manifest.js +3 -0
- data/examples/pusher-fake/app/assets/images/.keep +0 -0
- data/examples/pusher-fake/app/assets/javascripts/application.js +21 -0
- data/examples/pusher-fake/app/assets/stylesheets/application.css +15 -0
- data/examples/pusher-fake/app/controllers/application_controller.rb +3 -0
- data/examples/pusher-fake/app/controllers/test_controller.rb +5 -0
- data/examples/pusher-fake/app/models/models.rb +2 -0
- data/examples/pusher-fake/app/models/public/.keep +0 -0
- data/examples/pusher-fake/app/models/public/application_record.rb +3 -0
- data/examples/pusher-fake/app/models/public/word.rb +2 -0
- data/examples/pusher-fake/app/policies/application_policy.rb +14 -0
- data/examples/pusher-fake/app/views/components.rb +16 -0
- data/examples/pusher-fake/app/views/components/app.rb +18 -0
- data/examples/pusher-fake/app/views/layouts/application.html.erb +14 -0
- data/examples/pusher-fake/app/views/layouts/mailer.html.erb +13 -0
- data/examples/pusher-fake/app/views/layouts/mailer.text.erb +1 -0
- data/examples/pusher-fake/bin/bundle +3 -0
- data/examples/pusher-fake/bin/rails +9 -0
- data/examples/pusher-fake/bin/rake +9 -0
- data/examples/pusher-fake/bin/setup +34 -0
- data/examples/pusher-fake/bin/spring +16 -0
- data/examples/pusher-fake/bin/update +29 -0
- data/examples/pusher-fake/config.ru +5 -0
- data/examples/pusher-fake/config/application.rb +20 -0
- data/examples/pusher-fake/config/boot.rb +3 -0
- data/examples/pusher-fake/config/database.yml +25 -0
- data/examples/pusher-fake/config/environment.rb +5 -0
- data/examples/pusher-fake/config/environments/development.rb +56 -0
- data/examples/pusher-fake/config/environments/production.rb +86 -0
- data/examples/pusher-fake/config/environments/test.rb +42 -0
- data/examples/pusher-fake/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/pusher-fake/config/initializers/assets.rb +11 -0
- data/examples/pusher-fake/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/pusher-fake/config/initializers/cookies_serializer.rb +5 -0
- data/examples/pusher-fake/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/pusher-fake/config/initializers/hyper_mesh.rb +21 -0
- data/examples/pusher-fake/config/initializers/inflections.rb +16 -0
- data/examples/pusher-fake/config/initializers/mime_types.rb +4 -0
- data/examples/pusher-fake/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/pusher-fake/config/initializers/session_store.rb +3 -0
- data/examples/pusher-fake/config/initializers/wrap_parameters.rb +14 -0
- data/examples/pusher-fake/config/locales/en.yml +23 -0
- data/examples/pusher-fake/config/puma.rb +47 -0
- data/examples/pusher-fake/config/routes.rb +5 -0
- data/examples/pusher-fake/config/secrets.yml +22 -0
- data/examples/pusher-fake/config/spring.rb +6 -0
- data/examples/{simple-poller/db/migrate/20161013220135_create_words.rb → pusher-fake/db/migrate/20161114213840_create_words.rb} +0 -0
- data/examples/pusher-fake/db/schema.rb +34 -0
- data/examples/pusher-fake/db/seeds.rb +7 -0
- data/examples/pusher-fake/lib/assets/.keep +0 -0
- data/examples/pusher-fake/lib/tasks/.keep +0 -0
- data/examples/pusher-fake/log/.keep +0 -0
- data/examples/pusher-fake/public/404.html +67 -0
- data/examples/pusher-fake/public/422.html +67 -0
- data/examples/pusher-fake/public/500.html +66 -0
- data/examples/pusher-fake/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/pusher-fake/public/apple-touch-icon.png +0 -0
- data/examples/pusher-fake/public/favicon.ico +0 -0
- data/examples/pusher-fake/public/robots.txt +5 -0
- data/examples/pusher-fake/test/controllers/.keep +0 -0
- data/examples/pusher-fake/test/fixtures/.keep +0 -0
- data/examples/pusher-fake/test/fixtures/files/.keep +0 -0
- data/examples/pusher-fake/test/fixtures/words.yml +7 -0
- data/examples/pusher-fake/test/helpers/.keep +0 -0
- data/examples/pusher-fake/test/integration/.keep +0 -0
- data/examples/pusher-fake/test/mailers/.keep +0 -0
- data/examples/pusher-fake/test/models/.keep +0 -0
- data/examples/pusher-fake/test/models/word_test.rb +7 -0
- data/examples/pusher-fake/test/test_helper.rb +10 -0
- data/examples/pusher-fake/tmp/.keep +0 -0
- data/examples/pusher-fake/vendor/assets/javascripts/.keep +0 -0
- data/examples/pusher-fake/vendor/assets/stylesheets/.keep +0 -0
- data/examples/pusher/.gitignore +21 -0
- data/examples/pusher/Gemfile +58 -0
- data/examples/pusher/Gemfile.lock +236 -0
- data/examples/pusher/README.md +24 -0
- data/examples/pusher/Rakefile +6 -0
- data/examples/pusher/app/assets/config/manifest.js +3 -0
- data/examples/pusher/app/assets/images/.keep +0 -0
- data/examples/pusher/app/assets/javascripts/application.js +21 -0
- data/examples/pusher/app/assets/stylesheets/application.css +15 -0
- data/examples/pusher/app/controllers/application_controller.rb +3 -0
- data/examples/pusher/app/controllers/test_controller.rb +5 -0
- data/examples/pusher/app/models/models.rb +2 -0
- data/examples/pusher/app/models/public/.keep +0 -0
- data/examples/pusher/app/models/public/application_record.rb +3 -0
- data/examples/pusher/app/models/public/word.rb +2 -0
- data/examples/pusher/app/policies/application_policy.rb +14 -0
- data/examples/pusher/app/views/components.rb +16 -0
- data/examples/pusher/app/views/components/app.rb +18 -0
- data/examples/pusher/app/views/layouts/application.html.erb +14 -0
- data/examples/pusher/app/views/layouts/mailer.html.erb +13 -0
- data/examples/pusher/app/views/layouts/mailer.text.erb +1 -0
- data/examples/pusher/bin/bundle +3 -0
- data/examples/pusher/bin/rails +9 -0
- data/examples/pusher/bin/rake +9 -0
- data/examples/pusher/bin/setup +34 -0
- data/examples/pusher/bin/spring +16 -0
- data/examples/pusher/bin/update +29 -0
- data/examples/pusher/config.ru +5 -0
- data/examples/pusher/config/application.rb +20 -0
- data/examples/pusher/config/boot.rb +3 -0
- data/examples/pusher/config/database.yml +25 -0
- data/examples/pusher/config/environment.rb +5 -0
- data/examples/pusher/config/environments/development.rb +56 -0
- data/examples/pusher/config/environments/production.rb +86 -0
- data/examples/pusher/config/environments/test.rb +42 -0
- data/examples/pusher/config/initializers/application_controller_renderer.rb +6 -0
- data/examples/pusher/config/initializers/assets.rb +11 -0
- data/examples/pusher/config/initializers/backtrace_silencers.rb +7 -0
- data/examples/pusher/config/initializers/cookies_serializer.rb +5 -0
- data/examples/pusher/config/initializers/filter_parameter_logging.rb +4 -0
- data/examples/pusher/config/initializers/hyper_mesh.rb +10 -0
- data/examples/pusher/config/initializers/inflections.rb +16 -0
- data/examples/pusher/config/initializers/mime_types.rb +4 -0
- data/examples/pusher/config/initializers/new_framework_defaults.rb +24 -0
- data/examples/pusher/config/initializers/session_store.rb +3 -0
- data/examples/pusher/config/initializers/wrap_parameters.rb +14 -0
- data/examples/pusher/config/locales/en.yml +23 -0
- data/examples/pusher/config/puma.rb +47 -0
- data/examples/pusher/config/routes.rb +5 -0
- data/examples/pusher/config/secrets.yml +22 -0
- data/examples/pusher/config/spring.rb +6 -0
- data/examples/pusher/db/migrate/20161114213840_create_words.rb +9 -0
- data/examples/pusher/db/schema.rb +34 -0
- data/examples/pusher/db/seeds.rb +7 -0
- data/examples/pusher/lib/assets/.keep +0 -0
- data/examples/pusher/lib/tasks/.keep +0 -0
- data/examples/pusher/log/.keep +0 -0
- data/examples/pusher/public/404.html +67 -0
- data/examples/pusher/public/422.html +67 -0
- data/examples/pusher/public/500.html +66 -0
- data/examples/pusher/public/apple-touch-icon-precomposed.png +0 -0
- data/examples/pusher/public/apple-touch-icon.png +0 -0
- data/examples/pusher/public/favicon.ico +0 -0
- data/examples/pusher/public/robots.txt +5 -0
- data/examples/pusher/test/controllers/.keep +0 -0
- data/examples/pusher/test/fixtures/.keep +0 -0
- data/examples/pusher/test/fixtures/files/.keep +0 -0
- data/examples/pusher/test/fixtures/words.yml +7 -0
- data/examples/pusher/test/helpers/.keep +0 -0
- data/examples/pusher/test/integration/.keep +0 -0
- data/examples/pusher/test/mailers/.keep +0 -0
- data/examples/pusher/test/models/.keep +0 -0
- data/examples/pusher/test/models/word_test.rb +7 -0
- data/examples/pusher/test/test_helper.rb +10 -0
- data/examples/pusher/tmp/.keep +0 -0
- data/examples/pusher/vendor/assets/javascripts/.keep +0 -0
- data/examples/pusher/vendor/assets/stylesheets/.keep +0 -0
- data/examples/simple-poller/Gemfile +7 -14
- data/examples/simple-poller/Gemfile.lock +23 -66
- data/examples/simple-poller/app/assets/javascripts/application.js +5 -4
- data/examples/simple-poller/app/controllers/test_controller.rb +0 -1
- data/examples/simple-poller/app/policies/application_policy.rb +10 -1
- data/examples/simple-poller/app/views/components.rb +4 -6
- data/examples/simple-poller/app/views/components/app.rb +2 -24
- data/examples/simple-poller/app/views/layouts/application.html.erb +1 -1
- data/examples/simple-poller/bin/bundle +0 -0
- data/examples/simple-poller/bin/rails +0 -0
- data/examples/simple-poller/bin/rake +0 -0
- data/examples/simple-poller/bin/setup +0 -0
- data/examples/simple-poller/bin/spring +0 -0
- data/examples/simple-poller/bin/update +0 -0
- data/examples/simple-poller/config/application.rb +1 -1
- data/examples/simple-poller/config/environments/development.rb +13 -1
- data/examples/simple-poller/config/environments/production.rb +1 -1
- data/examples/simple-poller/config/initializers/hyper_mesh.rb +9 -0
- data/examples/simple-poller/config/initializers/session_store.rb +1 -1
- data/examples/simple-poller/config/routes.rb +1 -1
- data/examples/simple-poller/config/secrets.yml +2 -2
- data/examples/simple-poller/db/migrate/20161114213840_create_words.rb +9 -0
- data/examples/simple-poller/db/schema.rb +14 -1
- data/lib/hypermesh/version.rb +1 -1
- data/lib/reactive_record/active_record/reactive_record/dummy_value.rb +2 -0
- data/spec/synchromesh/{connection_spec.rb → unit_tests/connection_spec.rb} +0 -0
- data/spec/synchromesh/unit_tests/dummy_value_spec.rb +26 -0
- metadata +184 -20
- data/examples/action-cable/config/initializers/synchromesh.rb +0 -5
- data/examples/action-cable/rails_cache_dir2/C91/480/synchromesh_active_connections +0 -0
- data/examples/simple-poller/app/helpers/application_helper.rb +0 -2
- data/examples/simple-poller/app/jobs/application_job.rb +0 -2
- data/examples/simple-poller/app/mailers/application_mailer.rb +0 -4
- data/examples/simple-poller/config/cable.yml +0 -9
- data/examples/simple-poller/config/initializers/synchromesh.rb +0 -15
- data/hyper-mesh-0.4.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06482f0ee34e8ee178f10efe5c5425a8fa0268fe
|
4
|
+
data.tar.gz: f8588709cf6970fae4b300418925533757421286
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4e34b870273c9e7dbaba3bc8788bd45e27cee418f272ec65957292656bfa76e51933d0e8bcf49ab178d93f5ba3dee8de36ead41229b3806f774494e8b9223eb9
|
7
|
+
data.tar.gz: ea01368f7c042bde2b004b17fa462829b2cfd6cd39d83c8542b50c3555a0f0eaaa62e4f47dd3f2c776848dfdf0e3f22020adc032ac71cbf6374a205a8c836484
|
data/README.md
CHANGED
@@ -63,7 +63,14 @@ class WordOfTheDay < React::Component::Base
|
|
63
63
|
BUTTON { 'pick another' }.on(:click) { pick_entry! }
|
64
64
|
end
|
65
65
|
end
|
66
|
-
```
|
66
|
+
```
|
67
|
+
|
68
|
+
For more complete examples with *push* updates checkout any of the apps in the `examples` directory, or build your own in 5 minutes following one of the quickstart guides:
|
69
|
+
|
70
|
+
+ [Rails 5 with ActionCable](/docs/action_cable_quickstart.md)
|
71
|
+
+ [Using Pusher.com](/docs/pusher_quickstart.md)
|
72
|
+
+ [Using Pusher-Faker](/docs/pusher_quickstart.md)
|
73
|
+
+ [Using Simple Polling](/docs/simple_poller_quickstart.md)
|
67
74
|
|
68
75
|
## Basic Installation and Setup
|
69
76
|
|
@@ -95,19 +102,18 @@ After restarting, and reloading your browsers you will see changes broadcast to
|
|
95
102
|
|
96
103
|
For setting up the other possible transports following one of these guides:
|
97
104
|
|
98
|
-
|
105
|
+
+ [Rails 5 with ActionCable](/docs/action_cable_quickstart.md)
|
106
|
+
+ [Using Pusher.com](/docs/pusher_quickstart.md)
|
107
|
+
+ [Using Pusher-Faker](/docs/pusher_quickstart.md)
|
108
|
+
+ [Using Simple Polling](/docs/simple_poller_quickstart.md)
|
99
109
|
|
100
|
-
|
110
|
+
## Advanced Configuration
|
101
111
|
|
102
|
-
|
103
|
-
|
104
|
-
## Basic Configuration
|
105
|
-
|
106
|
-
For complete details on configuration settings go [here](/docs/configuration_details.md)
|
112
|
+
The above guides will work in most cases, but for complete details on configuration settings go [here](/docs/configuration_details.md)
|
107
113
|
|
108
114
|
## ActiveRecord API
|
109
115
|
|
110
|
-
HyperMesh uses a large subset of the ActiveRecord API modified only when necessary to accommodate the asynchronous nature of the client.
|
116
|
+
HyperMesh uses a large subset of the ActiveRecord API modified only when necessary to accommodate the asynchronous nature of the client. You can access your ActiveRecord models just like you would in models, controllers, or in ERB or HAML view templates.
|
111
117
|
|
112
118
|
See this [guide](/docs/activerecord_api.md) for details.
|
113
119
|
|
@@ -115,7 +121,7 @@ See this [guide](/docs/activerecord_api.md) for details.
|
|
115
121
|
|
116
122
|
## Client Side Scoping
|
117
123
|
|
118
|
-
By default scopes will be recalculated on the server.
|
124
|
+
By default scopes will be recalculated on the server. For simple scopes that do not use joins or includes no additional action needs to be taken to make scopes work with HyperMesh. For scopes that do use joins, or if you want to offload the scoping computation from the server to the client read more [here.](docs/client_side_scoping.md)
|
119
125
|
|
120
126
|
## Authorization
|
121
127
|
|
@@ -141,7 +147,7 @@ this results in an error like this:
|
|
141
147
|
Exception raised while rendering #<TopLevelRailsComponent:0x53e>
|
142
148
|
ReferenceError: Pusher is not defined
|
143
149
|
```
|
144
|
-
To resolve make sure you `require 'pusher'` in your application.js file if using pusher.
|
150
|
+
To resolve make sure you `require 'pusher'` in your application.js file if using pusher. **DO NOT** require pusher from your components manifest as this will cause prerendering to fail.
|
145
151
|
|
146
152
|
- No create/update/destroy policies
|
147
153
|
You must explicitly allow changes to the models to be made by the client. If you don't you will
|
@@ -177,11 +183,11 @@ You are still referencing the old reactive-ruby or reactrb gems either directly
|
|
177
183
|
|
178
184
|
Sometimes you need to figure out what connections are available, or what attributes are readable etc.
|
179
185
|
|
180
|
-
Its all to do with your policies, but perhaps you just need a little investigation.
|
186
|
+
Its usually all to do with your policies, but perhaps you just need a little investigation.
|
181
187
|
|
182
188
|
You can bring up a console within the controller context by browsing `localhost:3000/rr/console`
|
183
189
|
|
184
|
-
*Note: change `rr` to wherever you are mounting
|
190
|
+
*Note: change `rr` to wherever you are mounting HyperMesh in your routes file.*
|
185
191
|
|
186
192
|
*Note: in rails 4, you will need to add the gem 'web-console' to your development section*
|
187
193
|
|
@@ -219,6 +225,8 @@ You can of course simulate server side changes to your models through this conso
|
|
219
225
|
|
220
226
|
## Development
|
221
227
|
|
228
|
+
HyperMesh is the merger of `reactive-record` and `synchromesh` gems. As such a lot of the internal names are still using either ReactiveRecord or Synchromesh module names.
|
229
|
+
|
222
230
|
The original `ReactiveRecord` specs were written in opal-rspec. These are being migrated to
|
223
231
|
use server rspec with isomorphic helpers. There are about 170 of the original tests left and to run these you
|
224
232
|
|
@@ -31,14 +31,11 @@ If you are already using ActionCable in your app that is fine, as HyperMesh will
|
|
31
31
|
|
32
32
|
Otherwise go through the following steps to setup ActionCable.
|
33
33
|
|
34
|
-
##### Make sure the `action_cable` js file in your assets
|
34
|
+
##### Make sure the `action_cable` js file is required in your assets
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
//= require action_cable
|
40
|
-
Opal.load('components');
|
41
|
-
```
|
36
|
+
Typically `app/assets/javascripts/application.js` will finish with a `require_tree .` and this will pull in the `cable.js` file which will pull in `action_cable.js`
|
37
|
+
|
38
|
+
However at a minimum if `application.js` simply does a `require action_cable` that will be sufficient for HyperMesh.
|
42
39
|
|
43
40
|
##### Make sure you have a cable.yml file
|
44
41
|
|
@@ -74,6 +71,11 @@ If you don't already have a model to play with, add one now:
|
|
74
71
|
|
75
72
|
`bundle exec rake db:migrate`
|
76
73
|
|
74
|
+
Move `app/models/word.rb` to `app/models/public/word.rb` and move
|
75
|
+
`app/models/application_record.rb` to `app/models/public/application_record.rb`
|
76
|
+
|
77
|
+
**Leave** `app/models/model.rb` where it is. This is your models client side manifest file.
|
78
|
+
|
77
79
|
Whatever model(s) you will plan to access on the client need to moved to the `app/models/public` directory. This allows reactive-record to build a client side proxy for the models. Models not moved will be completely invisible on the client side.
|
78
80
|
|
79
81
|
**Important** in rails 5 there is also a base `ApplicationRecord` class, that all other models are built from. This class must be moved to the public directory as well.
|
@@ -0,0 +1,73 @@
|
|
1
|
+
## ActiveRecord API
|
2
|
+
|
3
|
+
HyperMesh uses a subset of the standard ActiveRecord API to give your client side HyperReact components access to your server side models.
|
4
|
+
|
5
|
+
### Class Methods
|
6
|
+
|
7
|
+
`scope` and `default_scope`: HyperMesh adds four new options to these methods: `joins`, `client`, `select` and `server`. The `joins` option provides information on how the scope will be joined with other models. The `client` and `select` options allow scoping to be done on the client side to offload this from the server, and the `server` option is there just for symmetry with the othe options. See the [Client Side Scoping](/docs/client_side_scoping.md) page for more details.
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
# the scope proc is executed on the server
|
11
|
+
scope :active, -> () { where(completed: true) }
|
12
|
+
|
13
|
+
# if the scope does a join (or include) this must be indicated
|
14
|
+
# using the joins: option.
|
15
|
+
scope :with_recent_comments,
|
16
|
+
-> { joins(:comments).where('comment.created_at >= ?', Time.now-1.week) },
|
17
|
+
joins: ['comments'] # or joins: 'comments'
|
18
|
+
|
19
|
+
# the server side proc can be indicated by the server: option
|
20
|
+
# an optional client side proc can be provided to compute the scope
|
21
|
+
# locally at the client
|
22
|
+
scope :completed,
|
23
|
+
server: -> { where(complete: true) }
|
24
|
+
client: -> { complete }
|
25
|
+
```
|
26
|
+
|
27
|
+
`unscoped` and `all`: These builtin scopes work just like standard ActiveRecord.
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
Word.all.each { |word| LI { word.text }}
|
31
|
+
```
|
32
|
+
|
33
|
+
`belongs_to, has_many, has_one`: These all work as on the server. However it is important that you fully specify both sides of the relationship. This is not always necessary on the server because ActiveRecord uses the table schema to work things out.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
class Todo < ActiveRecord::Base
|
37
|
+
belongs_to :assigned_to, class_name: 'User'
|
38
|
+
end
|
39
|
+
|
40
|
+
class User < ActiveRecord::Base
|
41
|
+
has_many :todos, foreign_key: 'assigned_to_id'
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
`composed_of`: You can create aggregate models like ActiveRecord.
|
46
|
+
|
47
|
+
`column_names`: returns a list of the database columns.
|
48
|
+
|
49
|
+
`columns_hash`: returns the details of the columns specification. Note that on the server `columns_hash` returns a hash of objects specifying column information. On the client the entire structure is just one big hash of hashes.
|
50
|
+
|
51
|
+
`abstract_class=`, `abstract_class?`, `primary_key`, `primary_key=`, `inheritance_column`, `inheritance_column=`, `model_name`: All work as on the server. See ActiveRecord documentation for more info.
|
52
|
+
|
53
|
+
`new`: Takes a hash of attributes and initializes a new unsaved record. The values of any attributes not specified in the hash will be taken from the models default values specified in the `columns_hash`.
|
54
|
+
|
55
|
+
If new is passed a native javascript object it will be treated as a hash and converted accordingly.
|
56
|
+
|
57
|
+
`create`: Short hand for `new(...).save`. See the `save` instance method for details on how saving is done.
|
58
|
+
|
59
|
+
`limit` and `offset`: These builtin scopes behave as they do on the server:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
Word.offset(500).limit(20) # get words 500-519
|
63
|
+
```
|
64
|
+
|
65
|
+
`find`: takes an id and returns the corresponding record.
|
66
|
+
|
67
|
+
`find_by`: takes single item hash indicating an attribute value pair to find.
|
68
|
+
|
69
|
+
`find_by_...`: i.e. `find_by_first_name` these will find the first record with a matching attribute.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
Word.find_by_text('hello') # short for Word.find_by(text: 'hello')
|
73
|
+
```
|
data/docs/client_side_scoping.md
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
When the client receives notification that a record has changed HyperMesh finds the set of currently rendered scopes that might be effected, and requests them to be updated from the server.
|
4
4
|
|
5
|
-
On the server scopes are a useful way to structure code. **On the client** scopes are vital as they limit the amount of data loaded, viewed, and updated on the client. Consider a factory floor management system that shows *job* state as work flows through the factory. There may be millions of jobs that a production floor browser is authorized to view, but at any time there are probably only 50 being shown. Using ActiveRecord scopes is the way
|
5
|
+
On the server scopes are a useful way to structure code. **On the client** scopes are vital as they limit the amount of data loaded, viewed, and updated on the client. Consider a factory floor management system that shows *job* state as work flows through the factory. There may be millions of jobs that a production floor browser is authorized to view, but at any time there are probably only 50 being shown. Using ActiveRecord scopes is the way HyperMesh keeps the data requested by the browser limited to a reasonable amount.
|
6
6
|
|
7
7
|
To make scopes work efficiently on the client HyperMesh adds some features to the ActiveRecord `scope` and `default_scope` macros. Note you must use the `scope` macro (and not class methods) for things to work with HyperMesh.
|
8
8
|
|
9
9
|
The additional features are accessed via the `:joins`, `:client`, and `:select` options.
|
10
10
|
|
11
|
-
The `:joins` option tells the
|
11
|
+
The `:joins` option tells the HyperMesh client which models are joined with the scope. *You must add a `:joins` option if the scope has any data base join operations in it, otherwise if a joined model changes, HyperMesh will not know to update the scope.*
|
12
12
|
|
13
|
-
The `:client`
|
13
|
+
The `:client` and `:select` options provide the client a way to update scopes without having to contact the server. Unlike the `:joins` option this is an optimization and is not required for scopes to work.
|
14
14
|
|
15
15
|
```ruby
|
16
16
|
class Todo < ActiveRecord::Base
|
@@ -34,7 +34,7 @@ class Todo < ActiveRecord::Base
|
|
34
34
|
# Now with_recent_comments will be re-evaluated whenever a Todo record, or a Comment
|
35
35
|
# joined with a Todo change.
|
36
36
|
|
37
|
-
# Normally whenever
|
37
|
+
# Normally whenever HyperMesh detects that a scope may be effected by a changed
|
38
38
|
# model, it will request the scope be re-evaluated on the server. To offload this
|
39
39
|
# computation to the client provide a client side scope method:
|
40
40
|
|
@@ -46,7 +46,7 @@ class Todo < ActiveRecord::Base
|
|
46
46
|
# The client proc is executed on each candidate record, and if it returns true the record
|
47
47
|
# will be added to the scope.
|
48
48
|
|
49
|
-
# Instead of a client proc you can provide a select proc, which will receive the entire
|
49
|
+
# Instead of a client proc you can provide a select proc, which will receive the entire
|
50
50
|
# collection which can then be filtered and sorted.
|
51
51
|
|
52
52
|
scope :sort_by_created_at,
|
@@ -1,3 +1,14 @@
|
|
1
|
+
# HyperMesh Configuration
|
2
|
+
|
3
|
+
|
4
|
+
# ![](/work-in-progress-drinking.png) WARNING DOCS AND EXAMPLES ARE BEING REWRITTEN MANY LINKS MAY BE BROKEN STAY TUNED OR CHECK IN AT [![Join the chat at https://gitter.im/reactrb/chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/reactrb/chat?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) FOR MORE INFO
|
5
|
+
|
6
|
+
There are XXX parts to the HyperMesh configuration:
|
7
|
+
|
8
|
+
1. Model classes
|
9
|
+
2. Policies
|
10
|
+
3. Push Transport
|
11
|
+
|
1
12
|
## Installation
|
2
13
|
|
3
14
|
If you do not already have hyper-react installed, then use the reactrb-rails-generator gem to setup hyper-react, reactive-record and associated gems.
|
@@ -1,15 +1,39 @@
|
|
1
|
-
### Pusher-Fake
|
1
|
+
### Pusher-Fake Quickstart
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
The [Pusher-Fake](https://github.com/tristandunn/pusher-fake) gem will provide a transport using the same protocol as pusher.com. You can use it to locally test an app that will be put into production using pusher.com.
|
4
|
+
|
5
|
+
#### 1 Add the Pusher, Pusher-Fake and HyperLoop gems to your Rails app
|
6
|
+
|
7
|
+
- add `gem 'pusher'` to your Gemfile.
|
8
|
+
- add `gem 'pusher-fake'` to the development and test sections of your Gemfile.
|
9
|
+
|
10
|
+
If you have not already installed the `hyper-react` and `hyper-mesh` gems, then do so now using the [hyper-rails](https://github.com/ruby-hyperloop/hyper-rails) gem.
|
11
|
+
|
12
|
+
- add `gem 'hyper-rails'` to your gem file (in the development section)
|
13
|
+
- run `bundle install`
|
14
|
+
- run `rails g hyperloop:install --all` (make sure to use the --all option)
|
15
|
+
- run `bundle update`
|
16
|
+
|
17
|
+
#### 2 Add the pusher js file to your application.js file
|
5
18
|
|
6
19
|
```ruby
|
7
|
-
#
|
20
|
+
# app/assets/javascript/application.js
|
21
|
+
...
|
22
|
+
//= require 'hyper-mesh/pusher'
|
23
|
+
//= require_tree .
|
24
|
+
Opal.load('components');
|
25
|
+
```
|
26
|
+
|
27
|
+
#### 3 Set the transport
|
28
|
+
|
29
|
+
Once you have HyperMesh, and pusher installed then add this initializer:
|
30
|
+
```ruby
|
31
|
+
# typically app/config/initializers/HyperMesh.rb
|
8
32
|
# or you can do a similar setup in your tests (see this gem's specs)
|
9
33
|
require 'pusher'
|
10
34
|
require 'pusher-fake'
|
11
|
-
#
|
12
|
-
#
|
35
|
+
# Assign any values to the Pusher app_id, key, and secret config values.
|
36
|
+
# These can be fake values or the real values for your pusher account.
|
13
37
|
Pusher.app_id = "MY_TEST_ID" # you use the real or fake values
|
14
38
|
Pusher.key = "MY_TEST_KEY"
|
15
39
|
Pusher.secret = "MY_TEST_SECRET"
|
@@ -26,3 +50,68 @@ HyperMesh.configuration do |config|
|
|
26
50
|
}.merge(PusherFake.configuration.web_options)
|
27
51
|
end
|
28
52
|
```
|
53
|
+
|
54
|
+
#### 4 Try It Out
|
55
|
+
|
56
|
+
If you don't already have a model to play with, add one now:
|
57
|
+
|
58
|
+
`bundle exec rails generate model Word text:string`
|
59
|
+
|
60
|
+
`bundle exec rake db:migrate`
|
61
|
+
|
62
|
+
Move `app/models/word.rb` to `app/models/public/word.rb`
|
63
|
+
|
64
|
+
**Leave** `app/models/model.rb` where it is. This is your models client side manifest file.
|
65
|
+
|
66
|
+
Whatever model(s) you will plan to access on the client need to moved to the `app/models/public` directory. This allows reactive-record to build a client side proxy for the models. Models not moved will be completely invisible on the client side.
|
67
|
+
|
68
|
+
**Important** in rails 5 there is also a base `ApplicationRecord` class, that all other models are built from. This class must be moved to the public directory as well.
|
69
|
+
|
70
|
+
If you don't already have a component to play with, here is a simple one (make sure you added the Word model):
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# app/views/components/app.rb
|
74
|
+
class App < React::Component::Base
|
75
|
+
|
76
|
+
def add_new_word
|
77
|
+
# for fun we will use setgetgo.com to get random words!
|
78
|
+
HTTP.get("http://randomword.setgetgo.com/get.php", dataType: :jsonp) do |response|
|
79
|
+
Word.new(text: response.json[:Word]).save
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
render(DIV) do
|
84
|
+
SPAN { "Count of Words: #{Word.count}" }
|
85
|
+
BUTTON { "add another" }.on(:click) { add_new_word }
|
86
|
+
UL do
|
87
|
+
Word.each { |word| LI { word.text } }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
Add a controller:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
#app/controllers/test_controller.rb
|
97
|
+
class TestController < ApplicationController
|
98
|
+
def app
|
99
|
+
render_component
|
100
|
+
end
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
Add the `test` route to your routes file:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
#app/config/routes.rb
|
108
|
+
|
109
|
+
get 'test', to: 'test#app'
|
110
|
+
|
111
|
+
```
|
112
|
+
|
113
|
+
Fire up rails with `bundle exec rails s` and open your app in a couple of browsers. As data changes you should see them all updating together.
|
114
|
+
|
115
|
+
You can also fire up a rails console, and then for example do a `Word.new(text: "Hello").save` and again see any browsers updating.
|
116
|
+
|
117
|
+
If you want to go into more details with the example check out [words-example](/docs/words-example.md)
|
data/docs/pusher_quickstart.md
CHANGED
@@ -1,17 +1,105 @@
|
|
1
|
-
###
|
1
|
+
### PusherQuickstart
|
2
2
|
|
3
|
-
|
3
|
+
[Pusher.com](https://pusher.com/) provides a production ready push transport for your App. You can combine this with [Pusher-Fake](/docs/pusher_faker_quickstart.md) for local testing as well. You can get a free pusher account and API keys at [https://pusher.com](https://pusher.com)
|
4
|
+
|
5
|
+
#### 1 Add the Pusher and HyperLoop gems to your Rails app
|
6
|
+
|
7
|
+
- add `gem 'pusher'` to your Gemfile.
|
8
|
+
|
9
|
+
If you have not already installed the `hyper-react` and `hyper-mesh` gems, then do so now using the [hyper-rails](https://github.com/ruby-hyperloop/hyper-rails) gem.
|
10
|
+
|
11
|
+
- add `gem 'hyper-rails'` to your gem file (in the development section)
|
12
|
+
- run `bundle install`
|
13
|
+
- run `rails g hyperloop:install --all` (make sure to use the --all option)
|
14
|
+
- run `bundle update`
|
15
|
+
|
16
|
+
#### 2 Add the pusher js file to your application.js file
|
4
17
|
|
5
18
|
```ruby
|
6
|
-
#
|
19
|
+
# app/assets/javascript/application.js
|
20
|
+
...
|
21
|
+
//= require 'hyper-mesh/pusher'
|
22
|
+
//= require_tree .
|
23
|
+
Opal.load('components');
|
24
|
+
```
|
25
|
+
|
26
|
+
#### 3 Set the transport
|
27
|
+
|
28
|
+
Once you have HyperMesh and pusher installed then add this initializer:
|
29
|
+
```ruby
|
30
|
+
# config/initializers/HyperMesh.rb
|
7
31
|
HyperMesh.configuration do |config|
|
8
32
|
config.transport = :pusher
|
33
|
+
config.channel_prefix = "HyperMesh"
|
9
34
|
config.opts = {
|
10
|
-
app_id:
|
11
|
-
key:
|
12
|
-
secret:
|
13
|
-
encrypted: false # optional defaults to true
|
35
|
+
app_id: "2....9",
|
36
|
+
key: "f.....g",
|
37
|
+
secret: "1.......3"
|
14
38
|
}
|
15
|
-
config.channel_prefix = 'syncromesh' # or any other string you want
|
16
39
|
end
|
17
40
|
```
|
41
|
+
|
42
|
+
#### 4 Try It Out
|
43
|
+
|
44
|
+
If you don't already have a model to play with, add one now:
|
45
|
+
|
46
|
+
`bundle exec rails generate model Word text:string`
|
47
|
+
|
48
|
+
`bundle exec rake db:migrate`
|
49
|
+
|
50
|
+
Move `app/models/word.rb` to `app/models/public/word.rb`
|
51
|
+
|
52
|
+
**Leave** `app/models/model.rb` where it is. This is your models client side manifest file.
|
53
|
+
|
54
|
+
Whatever model(s) you will plan to access on the client need to moved to the `app/models/public` directory. This allows reactive-record to build a client side proxy for the models. Models not moved will be completely invisible on the client side.
|
55
|
+
|
56
|
+
**Important** in rails 5 there is also a base `ApplicationRecord` class, that all other models are built from. This class must be moved to the public directory as well.
|
57
|
+
|
58
|
+
If you don't already have a component to play with, here is a simple one (make sure you added the Word model):
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
# app/views/components/app.rb
|
62
|
+
class App < React::Component::Base
|
63
|
+
|
64
|
+
def add_new_word
|
65
|
+
# for fun we will use setgetgo.com to get random words!
|
66
|
+
HTTP.get("http://randomword.setgetgo.com/get.php", dataType: :jsonp) do |response|
|
67
|
+
Word.new(text: response.json[:Word]).save
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
render(DIV) do
|
72
|
+
SPAN { "Count of Words: #{Word.count}" }
|
73
|
+
BUTTON { "add another" }.on(:click) { add_new_word }
|
74
|
+
UL do
|
75
|
+
Word.each { |word| LI { word.text } }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
Add a controller:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
#app/controllers/test_controller.rb
|
85
|
+
class TestController < ApplicationController
|
86
|
+
def app
|
87
|
+
render_component
|
88
|
+
end
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
Add the `test` route to your routes file:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
#app/config/routes.rb
|
96
|
+
|
97
|
+
get 'test', to: 'test#app'
|
98
|
+
|
99
|
+
```
|
100
|
+
|
101
|
+
Fire up rails with `bundle exec rails s` and open your app in a couple of browsers. As data changes you should see them all updating together.
|
102
|
+
|
103
|
+
You can also fire up a rails console, and then for example do a `Word.new(text: "Hello").save` and again see any browsers updating.
|
104
|
+
|
105
|
+
If you want to go into more details with the example check out [words-example](/docs/words-example.md)
|