jason-rails 0.6.7 → 0.7.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/CHANGELOG.md +38 -0
- data/Gemfile.lock +6 -4
- data/README.md +16 -14
- data/app/controllers/jason/jason_controller.rb +26 -4
- data/app/workers/jason/outbound_message_queue_worker.rb +1 -1
- data/client/lib/JasonProvider.d.ts +2 -1
- data/client/lib/JasonProvider.js +2 -2
- data/client/lib/addRelations.d.ts +1 -0
- data/client/lib/addRelations.js +39 -0
- data/client/lib/createJasonReducers.js +4 -2
- data/client/lib/createOptDis.d.ts +1 -1
- data/client/lib/createOptDis.js +9 -8
- data/client/lib/createServerActionQueue.d.ts +3 -2
- data/client/lib/createServerActionQueue.js +32 -6
- data/client/lib/createServerActionQueue.test.js +61 -6
- data/client/lib/createThenable.d.ts +1 -0
- data/client/lib/createThenable.js +5 -0
- data/client/lib/index.d.ts +7 -1
- data/client/lib/index.js +3 -1
- data/client/lib/transportAdapters/actionCableAdapter.js +24 -4
- data/client/lib/transportAdapters/pusherAdapter.js +1 -1
- data/client/lib/useDraft.d.ts +1 -0
- data/client/lib/useDraft.js +13 -0
- data/client/lib/useEager.d.ts +1 -1
- data/client/lib/useEager.js +10 -5
- data/client/lib/useJason.d.ts +2 -1
- data/client/lib/useJason.js +4 -6
- data/client/package.json +1 -1
- data/client/src/JasonProvider.tsx +2 -2
- data/client/src/addRelations.ts +33 -0
- data/client/src/createJasonReducers.ts +4 -2
- data/client/src/createOptDis.ts +10 -8
- data/client/src/createServerActionQueue.test.ts +60 -6
- data/client/src/createServerActionQueue.ts +41 -6
- data/client/src/index.ts +2 -0
- data/client/src/transportAdapters/actionCableAdapter.ts +24 -5
- data/client/src/transportAdapters/pusherAdapter.ts +1 -2
- data/client/src/useDraft.ts +17 -0
- data/client/src/useEager.ts +9 -6
- data/client/src/useJason.ts +3 -6
- data/lib/jason.rb +4 -1
- data/lib/jason/api_model.rb +0 -4
- data/lib/jason/channel.rb +0 -7
- data/lib/jason/conditions_matcher.rb +88 -0
- data/lib/jason/consistency_checker.rb +65 -0
- data/lib/jason/graph_helper.rb +4 -0
- data/lib/jason/publisher.rb +39 -37
- data/lib/jason/subscription.rb +63 -18
- data/lib/jason/version.rb +1 -1
- metadata +12 -5
- data/client/src/makeEager.ts +0 -46
- data/lib/jason/publisher_old.rb +0 -112
- data/lib/jason/subscription_old.rb +0 -171
data/client/src/index.ts
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
import _JasonContext from './JasonContext'
|
1
2
|
import _JasonProvider from './JasonProvider'
|
2
3
|
import _useAct from './useAct'
|
3
4
|
import _useSub from './useSub'
|
4
5
|
import _useEager from './useEager'
|
5
6
|
|
7
|
+
export const JasonContext = _JasonContext
|
6
8
|
export const JasonProvider = _JasonProvider
|
7
9
|
export const useAct = _useAct
|
8
10
|
export const useSub = _useSub
|
@@ -1,6 +1,11 @@
|
|
1
1
|
import { createConsumer } from "@rails/actioncable"
|
2
|
+
import restClient from '../restClient'
|
3
|
+
import { v4 as uuidv4 } from 'uuid'
|
4
|
+
import _ from 'lodash'
|
2
5
|
|
3
6
|
export default function actionCableAdapter(jasonConfig, handlePayload, dispatch, onConnected) {
|
7
|
+
const consumerId = uuidv4()
|
8
|
+
|
4
9
|
const consumer = createConsumer()
|
5
10
|
const subscription = (consumer.subscriptions.create({
|
6
11
|
channel: 'Jason::Channel'
|
@@ -22,16 +27,30 @@ export default function actionCableAdapter(jasonConfig, handlePayload, dispatch,
|
|
22
27
|
}
|
23
28
|
}));
|
24
29
|
|
25
|
-
function getPayload(config, options) {
|
26
|
-
subscription.send({ getPayload: config, ...options })
|
27
|
-
}
|
28
|
-
|
29
30
|
function createSubscription(config) {
|
30
31
|
subscription.send({ createSubscription: config })
|
31
32
|
}
|
32
33
|
|
33
34
|
function removeSubscription(config) {
|
34
|
-
|
35
|
+
restClient.post('/jason/api/remove_subscription', { config, consumerId })
|
36
|
+
.catch(e => console.error(e))
|
37
|
+
}
|
38
|
+
|
39
|
+
function getPayload(config, options) {
|
40
|
+
restClient.post('/jason/api/get_payload', {
|
41
|
+
config,
|
42
|
+
options
|
43
|
+
})
|
44
|
+
.then(({ data }) => {
|
45
|
+
_.map(data, (payload, modelName) => {
|
46
|
+
handlePayload(payload)
|
47
|
+
})
|
48
|
+
})
|
49
|
+
.catch(e => console.error(e))
|
50
|
+
}
|
51
|
+
|
52
|
+
function fullChannelName(channelName) {
|
53
|
+
return channelName
|
35
54
|
}
|
36
55
|
|
37
56
|
return { getPayload, createSubscription, removeSubscription }
|
@@ -1,11 +1,10 @@
|
|
1
1
|
import Pusher from 'pusher-js'
|
2
|
-
import { createConsumer } from "@rails/actioncable"
|
3
2
|
import restClient from '../restClient'
|
4
3
|
import { v4 as uuidv4 } from 'uuid'
|
5
4
|
import _ from 'lodash'
|
6
5
|
|
7
6
|
export default function pusherAdapter(jasonConfig, handlePayload, dispatch) {
|
8
|
-
|
7
|
+
const consumerId = uuidv4()
|
9
8
|
|
10
9
|
const { pusherKey, pusherRegion, pusherChannelPrefix } = jasonConfig
|
11
10
|
const pusher = new Pusher(pusherKey, {
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import _ from 'lodash'
|
2
|
+
import { useSelector } from 'react-redux'
|
3
|
+
import addRelations from './addRelations'
|
4
|
+
|
5
|
+
/* Can be called as
|
6
|
+
useDraft() => draft object for making updates
|
7
|
+
useDraft('entity', id) => returns [draft, object]
|
8
|
+
useDraft('entity', id, relations) => returns [draft, objectWithEmbeddedRelations]
|
9
|
+
*/
|
10
|
+
|
11
|
+
export default function useDraft(entity, id, relations = []) {
|
12
|
+
// const entityDraft =`${entity}Draft`
|
13
|
+
// const object = { ...s[entityDraft].entities[String(id)] }
|
14
|
+
|
15
|
+
// return useSelector(s => addRelations(s, object, entity, relations, 'Draft'), _.isEqual)
|
16
|
+
}
|
17
|
+
|
data/client/src/useEager.ts
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
import
|
2
|
-
import {
|
1
|
+
import _ from 'lodash'
|
2
|
+
import { useSelector } from 'react-redux'
|
3
|
+
import addRelations from './addRelations'
|
3
4
|
|
4
|
-
export default function useEager(entity, id =
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
export default function useEager(entity: string, id = '', relations = [] as any) {
|
6
|
+
if (id) {
|
7
|
+
return useSelector(s => addRelations(s, { ...s[entity].entities[String(id)] }, entity, relations), _.isEqual)
|
8
|
+
} else {
|
9
|
+
return useSelector(s => addRelations(s, _.values(s[entity].entities), entity, relations), _.isEqual)
|
10
|
+
}
|
8
11
|
}
|
9
12
|
|
data/client/src/useJason.ts
CHANGED
@@ -9,13 +9,12 @@ import createTransportAdapater from './createTransportAdapter'
|
|
9
9
|
|
10
10
|
import { createEntityAdapter, createSlice, createReducer, configureStore } from '@reduxjs/toolkit'
|
11
11
|
|
12
|
-
import makeEager from './makeEager'
|
13
12
|
import { camelizeKeys } from 'humps'
|
14
13
|
import md5 from 'blueimp-md5'
|
15
14
|
import _ from 'lodash'
|
16
15
|
import React, { useState, useEffect } from 'react'
|
17
16
|
|
18
|
-
export default function useJason({ reducers, middleware = [], extraActions }: { reducers?: any, middleware?: any[], extraActions?: any }) {
|
17
|
+
export default function useJason({ reducers, middleware = [], enhancers = [], extraActions }: { reducers?: any, middleware?: any[], enhancers?: any[], extraActions?: any }) {
|
19
18
|
const [store, setStore] = useState(null as any)
|
20
19
|
const [value, setValue] = useState(null as any)
|
21
20
|
|
@@ -36,12 +35,11 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
36
35
|
|
37
36
|
console.debug({ allReducers })
|
38
37
|
|
39
|
-
const store = configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware(schema)] })
|
38
|
+
const store = configureStore({ reducer: allReducers, middleware: [...middleware, pruneIdsMiddleware(schema)], enhancers })
|
40
39
|
const dispatch = store.dispatch
|
41
40
|
|
42
41
|
const optDis = createOptDis(schema, dispatch, restClient, serverActionQueue)
|
43
42
|
const actions = createActions(schema, store, restClient, optDis, extraActions)
|
44
|
-
const eager = makeEager(schema)
|
45
43
|
|
46
44
|
let payloadHandlers = {}
|
47
45
|
let configs = {}
|
@@ -90,7 +88,7 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
90
88
|
function removeSubscription(config) {
|
91
89
|
transportAdapter.removeSubscription(config)
|
92
90
|
const md5Hash = md5(JSON.stringify(config))
|
93
|
-
payloadHandlers[md5Hash]
|
91
|
+
payloadHandlers[md5Hash]?.tearDown() // Race condition where component mounts then unmounts quickly
|
94
92
|
delete payloadHandlers[md5Hash]
|
95
93
|
delete configs[md5Hash]
|
96
94
|
delete subOptions[md5Hash]
|
@@ -99,7 +97,6 @@ export default function useJason({ reducers, middleware = [], extraActions }: {
|
|
99
97
|
setValue({
|
100
98
|
actions: actions,
|
101
99
|
subscribe: createSubscription,
|
102
|
-
eager,
|
103
100
|
handlePayload
|
104
101
|
})
|
105
102
|
setStore(store)
|
data/lib/jason.rb
CHANGED
@@ -12,6 +12,8 @@ require 'jason/engine'
|
|
12
12
|
require 'jason/lua_generator'
|
13
13
|
require 'jason/includes_helper'
|
14
14
|
require 'jason/graph_helper'
|
15
|
+
require 'jason/conditions_matcher'
|
16
|
+
require 'jason/consistency_checker'
|
15
17
|
|
16
18
|
module Jason
|
17
19
|
class Error < StandardError; end
|
@@ -23,7 +25,8 @@ module Jason
|
|
23
25
|
self.mattr_accessor :pusher_key
|
24
26
|
self.mattr_accessor :pusher_region
|
25
27
|
self.mattr_accessor :pusher_channel_prefix
|
26
|
-
self.mattr_accessor :
|
28
|
+
self.mattr_accessor :subscription_authorization_service
|
29
|
+
self.mattr_accessor :update_authorization_service
|
27
30
|
self.mattr_accessor :sidekiq_queue
|
28
31
|
|
29
32
|
self.schema = {}
|
data/lib/jason/api_model.rb
CHANGED
@@ -36,11 +36,7 @@ class Jason::ApiModel
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def permit(params)
|
39
|
-
pp self
|
40
|
-
pp params
|
41
39
|
params = params.require(:payload).permit(allowed_params).tap do |allowed|
|
42
|
-
pp "ALLOWED"
|
43
|
-
pp allowed
|
44
40
|
allowed_object_params.each do |key|
|
45
41
|
allowed[key] = params[:payload][key].to_unsafe_h if params[:payload][key]
|
46
42
|
end
|
data/lib/jason/channel.rb
CHANGED
@@ -12,7 +12,6 @@ class Jason::Channel < ActionCable::Channel::Base
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def handle_message(message)
|
15
|
-
pp message['createSubscription']
|
16
15
|
@subscriptions ||= []
|
17
16
|
|
18
17
|
begin # ActionCable swallows errors in this message - ensure they're output to logs.
|
@@ -38,18 +37,12 @@ class Jason::Channel < ActionCable::Channel::Base
|
|
38
37
|
|
39
38
|
subscriptions.push(subscription)
|
40
39
|
subscription.add_consumer(identifier)
|
41
|
-
subscription.get.each do |payload|
|
42
|
-
pp payload
|
43
|
-
transmit(payload) if payload.present?
|
44
|
-
end
|
45
40
|
end
|
46
41
|
|
47
42
|
def remove_subscription(config)
|
48
43
|
subscription = Jason::Subscription.upsert_by_config(config['model'], conditions: config['conditions'], includes: config['includes'])
|
49
44
|
subscriptions.reject! { |s| s.id == subscription.id }
|
50
45
|
subscription.remove_consumer(identifier)
|
51
|
-
|
52
|
-
# TODO Stop streams
|
53
46
|
end
|
54
47
|
|
55
48
|
def get_payload(config, force_refresh = false)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
class Jason::ConditionsMatcher
|
2
|
+
attr_reader :klass
|
3
|
+
|
4
|
+
def initialize(klass)
|
5
|
+
@klass = klass
|
6
|
+
end
|
7
|
+
|
8
|
+
# key, rules = 'post_id', 123
|
9
|
+
# key, rules = 'post_id', { 'value': [123,C456], 'type': 'between' }
|
10
|
+
# key, rules = 'post_id', { 'value': [123,456], 'type': 'between', 'not': true }
|
11
|
+
# key, rules = 'post_id', { 'value': 123, 'type': 'equals', 'not': true }
|
12
|
+
def test_match(key, rules, previous_changes)
|
13
|
+
return nil if !previous_changes.keys.include?(key)
|
14
|
+
|
15
|
+
if rules.is_a?(Hash)
|
16
|
+
matches = false
|
17
|
+
value = convert_to_datatype(key, rules['value'])
|
18
|
+
|
19
|
+
if rules['type'] == 'equals'
|
20
|
+
matches = previous_changes[key][1] == value
|
21
|
+
elsif rules['type'] == 'between'
|
22
|
+
matches = (value[0]..value[1]).cover?(previous_changes[key][1])
|
23
|
+
else
|
24
|
+
raise "Unrecognized rule type #{rules['type']}"
|
25
|
+
end
|
26
|
+
|
27
|
+
if rules['not']
|
28
|
+
return !matches
|
29
|
+
else
|
30
|
+
return matches
|
31
|
+
end
|
32
|
+
|
33
|
+
elsif rules.is_a?(Array)
|
34
|
+
value = convert_to_datatype(key, rules)
|
35
|
+
return previous_changes[key][1].includes?(value)
|
36
|
+
else
|
37
|
+
value = convert_to_datatype(key, rules)
|
38
|
+
return previous_changes[key][1] == value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# conditions = { 'post_id' => 123, 'created_at' => { 'type' => 'between', 'value' => ['2020-01-01', '2020-01-02'] } }
|
43
|
+
def apply_conditions(relation, conditions)
|
44
|
+
conditions.each do |key, rules|
|
45
|
+
relation = apply_condition(relation, key, rules)
|
46
|
+
end
|
47
|
+
|
48
|
+
relation
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def apply_condition(relation, key, rules)
|
54
|
+
if rules.is_a?(Hash)
|
55
|
+
value = convert_to_datatype(key, rules['value'])
|
56
|
+
|
57
|
+
if rules['type'] == 'equals'
|
58
|
+
arg = { key => value }
|
59
|
+
elsif rules['type'] == 'between'
|
60
|
+
arg = { key => value[0]..value[1] }
|
61
|
+
else
|
62
|
+
raise "Unrecognized rule type #{rules['type']}"
|
63
|
+
end
|
64
|
+
|
65
|
+
if rules['not']
|
66
|
+
return relation.where.not(arg)
|
67
|
+
else
|
68
|
+
return relation.where(arg)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
value = convert_to_datatype(key, rules)
|
72
|
+
return relation.where({ key => value })
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def convert_to_datatype(key, value)
|
77
|
+
datatype = klass.type_for_attribute(key).type
|
78
|
+
if datatype == :datetime || datatype == :date
|
79
|
+
if value.is_a?(Array)
|
80
|
+
value.map { |v| v&.to_datetime }
|
81
|
+
else
|
82
|
+
value&.to_datetime
|
83
|
+
end
|
84
|
+
else
|
85
|
+
value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
class Jason::ConsistencyChecker
|
2
|
+
attr_reader :subscription
|
3
|
+
attr_reader :inconsistent
|
4
|
+
|
5
|
+
def self.check_all(fix: false)
|
6
|
+
Jason::Subscription.all.each do |sub|
|
7
|
+
next if sub.consumer_count == 0
|
8
|
+
checker = Jason::ConsistencyChecker.new(sub)
|
9
|
+
result = checker.check
|
10
|
+
if checker.inconsistent?
|
11
|
+
pp sub.config
|
12
|
+
pp result
|
13
|
+
if fix
|
14
|
+
sub.reset!(hard: true)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.fix_all
|
21
|
+
check_all(fix: true)
|
22
|
+
end
|
23
|
+
|
24
|
+
def wipe_all_subs
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(subscription)
|
29
|
+
@subscription = subscription
|
30
|
+
@inconsistent = false
|
31
|
+
end
|
32
|
+
|
33
|
+
def inconsistent?
|
34
|
+
inconsistent
|
35
|
+
end
|
36
|
+
|
37
|
+
# Take a subscription, get the current cached payload, and compare it to the data retrieved from the database
|
38
|
+
def check
|
39
|
+
cached_payload = subscription.get
|
40
|
+
edge_set = subscription.load_ids_for_sub_models(subscription.model, nil)
|
41
|
+
|
42
|
+
result = cached_payload.map do |model_name, data|
|
43
|
+
cached_payload_instance_ids = data[:payload].map { |row| row['id'] }
|
44
|
+
|
45
|
+
model_idx = edge_set[:model_names].index(model_name)
|
46
|
+
if model_idx.present?
|
47
|
+
edge_set_instance_ids = edge_set[:instance_ids].map { |row| row[model_idx] }
|
48
|
+
else
|
49
|
+
next
|
50
|
+
end
|
51
|
+
|
52
|
+
missing = edge_set_instance_ids - cached_payload_instance_ids
|
53
|
+
intruding = cached_payload_instance_ids - edge_set_instance_ids
|
54
|
+
|
55
|
+
if missing.present? || intruding.present?
|
56
|
+
@inconsistent = true
|
57
|
+
end
|
58
|
+
|
59
|
+
[model_name, {
|
60
|
+
'missing' => missing,
|
61
|
+
'intruding' => intruding
|
62
|
+
}]
|
63
|
+
end.compact.to_h
|
64
|
+
end
|
65
|
+
end
|
data/lib/jason/graph_helper.rb
CHANGED
@@ -26,6 +26,10 @@ class Jason::GraphHelper
|
|
26
26
|
$redis_jason.srem("jason:subscriptions:#{id}:graph", edges)
|
27
27
|
end
|
28
28
|
|
29
|
+
def apply_add_node_at_root(node)
|
30
|
+
diff_edges_from_graph(add_edges: ["root/#{node}"])
|
31
|
+
end
|
32
|
+
|
29
33
|
def apply_remove_node(node)
|
30
34
|
edges = $redis_jason.smembers("jason:subscriptions:#{id}:graph")
|
31
35
|
edges = find_edges_with_node(edges, node)
|
data/lib/jason/publisher.rb
CHANGED
@@ -5,6 +5,7 @@ module Jason::Publisher
|
|
5
5
|
def self.cache_all
|
6
6
|
Rails.application.eager_load!
|
7
7
|
ActiveRecord::Base.descendants.each do |klass|
|
8
|
+
$redis_jason.del("jason:cache:#{klass.name.underscore}")
|
8
9
|
klass.cache_all if klass.respond_to?(:cache_all)
|
9
10
|
end
|
10
11
|
end
|
@@ -15,7 +16,7 @@ module Jason::Publisher
|
|
15
16
|
|
16
17
|
# Exists
|
17
18
|
if self.persisted? && (scope.blank? || self.class.unscoped.send(scope).exists?(self.id))
|
18
|
-
payload = self.
|
19
|
+
payload = self.as_json(as_json_config)
|
19
20
|
gidx = Jason::LuaGenerator.new.cache_json(self.class.name.underscore, self.id, payload)
|
20
21
|
return [payload, gidx]
|
21
22
|
# Has been destroyed
|
@@ -72,13 +73,38 @@ module Jason::Publisher
|
|
72
73
|
)
|
73
74
|
end
|
74
75
|
|
75
|
-
# - An instance is created where it belongs_to an _all_ subscription
|
76
|
-
if previous_changes['id'].present?
|
77
|
-
Jason::Subscription.add_id(self.class.name.underscore, id)
|
78
|
-
end
|
79
|
-
|
80
76
|
if persisted?
|
77
|
+
applied_sub_ids = []
|
78
|
+
|
79
|
+
jason_conditions.each do |row|
|
80
|
+
matches = row['conditions'].map do |key, rules|
|
81
|
+
Jason::ConditionsMatcher.new(self.class).test_match(key, rules, previous_changes)
|
82
|
+
end
|
83
|
+
next if matches.all? { |m| m.nil? } # None of the keys were in previous changes - therefore this condition does not apply
|
84
|
+
in_sub = matches.all? { |m| m }
|
85
|
+
|
86
|
+
if in_sub
|
87
|
+
row['subscription_ids'].each do |sub_id|
|
88
|
+
Jason::Subscription.find_by_id(sub_id).add_id(self.class.name.underscore, self.id)
|
89
|
+
applied_sub_ids.push(sub_id)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
row['subscription_ids'].each do |sub_id|
|
93
|
+
jason_subscriptions.each do |already_sub_id|
|
94
|
+
# If this sub ID already has this instance, remove it
|
95
|
+
if already_sub_id == sub_id
|
96
|
+
sub = Jason::Subscription.find_by_id(already_sub_id)
|
97
|
+
sub.remove_id(self.class.name.underscore, self.id)
|
98
|
+
applied_sub_ids.push(already_sub_id)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
81
105
|
jason_subscriptions.each do |sub_id|
|
106
|
+
next if applied_sub_ids.include?(sub_id)
|
107
|
+
|
82
108
|
Jason::Subscription.new(id: sub_id).update(self.class.name.underscore, id, payload, gidx)
|
83
109
|
end
|
84
110
|
end
|
@@ -93,13 +119,17 @@ module Jason::Publisher
|
|
93
119
|
Jason::Subscription.for_instance(self.class.name.underscore, id)
|
94
120
|
end
|
95
121
|
|
122
|
+
def jason_conditions
|
123
|
+
Jason::Subscription.conditions_for_model(self.class.name.underscore)
|
124
|
+
end
|
125
|
+
|
96
126
|
def jason_cached_value
|
97
127
|
JSON.parse($redis_jason.hget("jason:cache:#{self.class.name.underscore}", id) || '{}')
|
98
128
|
end
|
99
129
|
|
100
130
|
class_methods do
|
101
131
|
def cache_all
|
102
|
-
all.
|
132
|
+
all.find_each(&:cache_json)
|
103
133
|
end
|
104
134
|
|
105
135
|
def has_jason?
|
@@ -117,36 +147,8 @@ module Jason::Publisher
|
|
117
147
|
self.after_initialize -> {
|
118
148
|
@api_model = Jason::ApiModel.new(self.class.name.underscore)
|
119
149
|
}
|
120
|
-
self.after_commit :
|
121
|
-
|
122
|
-
|
123
|
-
def find_or_create_by_id(params)
|
124
|
-
object = find_by(id: params[:id])
|
125
|
-
|
126
|
-
if object
|
127
|
-
object.update(params)
|
128
|
-
elsif params[:hidden]
|
129
|
-
return false ## If an object is passed with hidden = true but didn't already exist, it's safe to never create it
|
130
|
-
else
|
131
|
-
object = create!(params)
|
132
|
-
end
|
133
|
-
|
134
|
-
object
|
135
|
-
end
|
136
|
-
|
137
|
-
def find_or_create_by_id!(params)
|
138
|
-
object = find_by(id: params[:id])
|
139
|
-
|
140
|
-
if object
|
141
|
-
object.update!(params)
|
142
|
-
elsif params[:hidden]
|
143
|
-
## TODO: We're diverging from semantics of the Rails bang! methods here, which would normally either raise or return an object. Find a way to make this better.
|
144
|
-
return false ## If an object is passed with hidden = true but didn't already exist, it's safe to never create it
|
145
|
-
else
|
146
|
-
object = create!(params)
|
147
|
-
end
|
148
|
-
|
149
|
-
object
|
150
|
+
self.after_commit :force_publish_json, on: [:create, :destroy]
|
151
|
+
self.after_commit :publish_json_if_changed, on: [:update]
|
150
152
|
end
|
151
153
|
end
|
152
154
|
|