menilite 0.4.2 → 0.5.0
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/Rakefile +1 -1
- data/lib/menilite.rb +3 -1
- data/lib/menilite/client/deserializer.rb +28 -0
- data/lib/menilite/client/http.rb +69 -0
- data/lib/menilite/client/store.rb +17 -19
- data/lib/menilite/controller.rb +1 -2
- data/lib/menilite/model.rb +101 -68
- data/lib/menilite/model/association.rb +45 -0
- data/lib/menilite/server/activerecord_store.rb +5 -3
- data/lib/menilite/server/router.rb +9 -4
- data/lib/menilite/server/serializer.rb +27 -0
- data/lib/menilite/server/store.rb +6 -2
- data/lib/menilite/version.rb +1 -1
- data/menilite.gemspec +1 -2
- metadata +9 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa0456ba69383e0e59a40b7b7fad44296b9f5576
|
4
|
+
data.tar.gz: f74ce6a6826bc2b73108a64c98aabba159078507
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d37414bfd1a1b040ffe0b5f11f3a77b2e75e90762a788f45ccae8a764c204ac63edf893754ef85517b443e0b6f285a09e217da0533621a5795c0c46605e5abf7
|
7
|
+
data.tar.gz: c9f86a5dbef6f88bb4ff07d080756f443576f16beefc19de56c95681f23e6a566f30f2382fa9bba8ea97aeb4a7972b7097ea2a61e741467a0697dbd88d7b1999
|
data/Rakefile
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'opal'
|
2
|
-
require 'opal-browser'
|
3
2
|
require 'opal/rspec/rake_task'
|
4
3
|
require "bundler/gem_tasks"
|
5
4
|
|
6
5
|
Opal::RSpec::RakeTask.new(:default) do |server, task|
|
7
6
|
task.pattern = 'spec/opal/**/*_spec.rb'
|
7
|
+
task.file = [ENV['FILE']] if ENV['FILE']
|
8
8
|
server.append_path File.expand_path('../lib', __FILE__)
|
9
9
|
server.source_map = true
|
10
10
|
server.debug = true
|
data/lib/menilite.rb
CHANGED
@@ -4,9 +4,10 @@ require "menilite/helper"
|
|
4
4
|
|
5
5
|
if RUBY_ENGINE == "opal"
|
6
6
|
require 'native'
|
7
|
-
require 'browser'
|
8
7
|
require 'menilite/model'
|
9
8
|
require 'menilite/controller'
|
9
|
+
require 'menilite/client/http'
|
10
|
+
require 'menilite/client/deserializer'
|
10
11
|
require 'menilite/client/store'
|
11
12
|
else
|
12
13
|
require 'opal'
|
@@ -14,6 +15,7 @@ else
|
|
14
15
|
require 'menilite/controller'
|
15
16
|
require 'menilite/server/error_with_status_code'
|
16
17
|
require 'menilite/server/privilege'
|
18
|
+
require 'menilite/server/serializer'
|
17
19
|
require 'menilite/server/router'
|
18
20
|
require 'menilite/server/activerecord_store'
|
19
21
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Menilite
|
2
|
+
module Deserializer
|
3
|
+
def self.deserialize(model_class, json, includes = nil)
|
4
|
+
case json
|
5
|
+
when Array
|
6
|
+
json.map {|j| deserialize(model_class, j, includes) }
|
7
|
+
when Hash
|
8
|
+
if includes
|
9
|
+
case includes
|
10
|
+
when String
|
11
|
+
assoc_data = json.delete(includes)
|
12
|
+
assoc_id = json.delete(:id)
|
13
|
+
obj = model_class.new(json)
|
14
|
+
assoc = obj.send(includes).model_class.new(assoc_data)
|
15
|
+
obj.send(includes + '=', assoc)
|
16
|
+
obj
|
17
|
+
when Array
|
18
|
+
raise "not implemented"
|
19
|
+
when Hash
|
20
|
+
raise "not implemented"
|
21
|
+
end
|
22
|
+
else
|
23
|
+
model_class.new(json)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Menilite
|
2
|
+
module Http
|
3
|
+
class << self
|
4
|
+
def get_json(url, &block)
|
5
|
+
(callback, promise) = prepare(url, &block)
|
6
|
+
|
7
|
+
`fetch(url).then(callback)`
|
8
|
+
|
9
|
+
promise
|
10
|
+
end
|
11
|
+
|
12
|
+
def post_json(url, json, &block)
|
13
|
+
(callback, promise) = prepare(url, &block)
|
14
|
+
|
15
|
+
`fetch(url, {method: 'post', body: JSON.stringify(json)}).then(callback)`
|
16
|
+
|
17
|
+
promise
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def prepare(url, &block)
|
24
|
+
promise = nil
|
25
|
+
callback = nil
|
26
|
+
|
27
|
+
if block
|
28
|
+
handler = ResponseHandler.new
|
29
|
+
handler.instance_eval(&block)
|
30
|
+
|
31
|
+
callback = Proc.new do |response|
|
32
|
+
if `response.ok`
|
33
|
+
%x(
|
34
|
+
response.json().then(function(json) {
|
35
|
+
#{handler.success(JSON.from_object(`json`))}
|
36
|
+
})
|
37
|
+
)
|
38
|
+
else
|
39
|
+
handler.failure(Native(response))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
else
|
43
|
+
promise = Promise.new
|
44
|
+
callback = Proc.new {|reponse| promise.resolve(JSON.from_object(response.json)) }
|
45
|
+
end
|
46
|
+
|
47
|
+
[callback, promise]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class ResponseHandler
|
52
|
+
def initialize
|
53
|
+
@listeners = {}
|
54
|
+
end
|
55
|
+
|
56
|
+
def on(evt, &block)
|
57
|
+
@listeners[evt] = block
|
58
|
+
end
|
59
|
+
|
60
|
+
def success(res)
|
61
|
+
@listeners[:success].call(res)
|
62
|
+
end
|
63
|
+
|
64
|
+
def failure
|
65
|
+
@listeners[:failure].call(res)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'browser/http'
|
2
|
-
|
3
1
|
module Menilite
|
4
2
|
class Store
|
5
3
|
def initialize
|
@@ -19,11 +17,7 @@ module Menilite
|
|
19
17
|
end
|
20
18
|
|
21
19
|
def find(model_class, id)
|
22
|
-
|
23
|
-
|
24
|
-
res = Browser::HTTP.get!("api/#{model_class.to_s}/#{id}")
|
25
|
-
model = model_class.new(res.json)
|
26
|
-
@tables[model_class][id] = model
|
20
|
+
self[model_class][id]
|
27
21
|
end
|
28
22
|
|
29
23
|
def save(model)
|
@@ -31,9 +25,9 @@ module Menilite
|
|
31
25
|
models = is_array ? model : [ model ]
|
32
26
|
model_class = models.first.class
|
33
27
|
table = @tables[model_class]
|
34
|
-
|
35
|
-
on :success do |
|
36
|
-
results =
|
28
|
+
Menilite::Http.post_json("api/#{model_class.to_s}", models.to_json) do
|
29
|
+
on :success do |json|
|
30
|
+
results = json.map do |value|
|
37
31
|
if table.has_key?(value[:id])
|
38
32
|
table[value[:id]].update(value)
|
39
33
|
table[value[:id]]
|
@@ -52,13 +46,14 @@ module Menilite
|
|
52
46
|
end
|
53
47
|
end
|
54
48
|
|
55
|
-
def fetch(model_class, filter: nil, order: nil, &block)
|
49
|
+
def fetch!(model_class, filter: nil, includes: nil, order: nil, &block)
|
56
50
|
tables = @tables
|
57
51
|
params = filter && (?? + filter.map {|k,v| "#{k}=#{v}" }.join(?&))
|
58
52
|
params = (params ? params + ?& : ??) + "order=#{[order].flatten.join(?,)}" if order
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
params = (params ? params + ?& : ??) + "includes=#{includes}" if includes
|
54
|
+
Menilite::Http.get_json("api/#{model_class}#{params}") do
|
55
|
+
on :success do |json|
|
56
|
+
tables[model_class] = json.map {|value| [value[:id], Menilite::Deserializer.deserialize(model_class, value, includes)] }.to_h
|
62
57
|
yield tables[model_class].values if block_given?
|
63
58
|
end
|
64
59
|
|
@@ -73,11 +68,14 @@ module Menilite
|
|
73
68
|
@tables[model_class] = {}
|
74
69
|
end
|
75
70
|
|
76
|
-
def max(model_class, field_name)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
71
|
+
def max!(model_class, field_name, &block)
|
72
|
+
Menilite::Http.get_json("api/#{model_class}?order=#{field_name}") do
|
73
|
+
on :success do |json|
|
74
|
+
if json.last
|
75
|
+
model = model_class.new(json.last)
|
76
|
+
yield model.fields[field_name]
|
77
|
+
end
|
78
|
+
end
|
81
79
|
end
|
82
80
|
end
|
83
81
|
end
|
data/lib/menilite/controller.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
if RUBY_ENGINE == 'opal'
|
2
|
-
require 'browser/http'
|
3
2
|
require 'opal-parser'
|
4
3
|
end
|
5
4
|
|
@@ -38,7 +37,7 @@ module Menilite
|
|
38
37
|
action_url = self.respond_to?(:namespace) ? "api/#{self.namespace}/#{name}" : "api/#{name}"
|
39
38
|
post_data = {}
|
40
39
|
post_data[:args] = args
|
41
|
-
|
40
|
+
Menilite::Http.post_json(action_url, post_data.to_json) do
|
42
41
|
on :success do |res|
|
43
42
|
callback.call(:success, res) if callback
|
44
43
|
end
|
data/lib/menilite/model.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'securerandom'
|
2
|
+
require_relative 'model/association'
|
2
3
|
|
3
4
|
if RUBY_ENGINE == 'opal'
|
4
|
-
require 'browser/http'
|
5
5
|
require 'opal-parser'
|
6
6
|
end
|
7
7
|
|
@@ -39,12 +39,12 @@ module Menilite
|
|
39
39
|
@guid = fields.delete(:id) || SecureRandom.uuid
|
40
40
|
|
41
41
|
self.class.field_info.select{|_, i| i.type == :reference}.each do |name, info|
|
42
|
-
fields[
|
42
|
+
fields[name] = Association.new(info.params[:class])
|
43
|
+
fields[name].load(fields["#{name}_id".to_sym]) if fields["#{name}_id".to_sym]
|
43
44
|
end
|
44
45
|
|
45
46
|
fields.each{|k, v| type_validate(k, v) }
|
46
47
|
fields = fields.map{|k,v| [k, convert_value(self.class.field_info[k].type, v)] }.to_h
|
47
|
-
|
48
48
|
if server?
|
49
49
|
fields.merge!(self.class.privilege_fields)
|
50
50
|
end
|
@@ -116,7 +116,7 @@ module Menilite
|
|
116
116
|
|
117
117
|
def save(collection, &block)
|
118
118
|
self.init
|
119
|
-
|
119
|
+
collection.each {|obj| obj.validate_all }
|
120
120
|
self.store.save(collection, &block)
|
121
121
|
end
|
122
122
|
|
@@ -130,30 +130,50 @@ module Menilite
|
|
130
130
|
store.delete(self)
|
131
131
|
end
|
132
132
|
|
133
|
-
def fetch(filter: {}, order: nil)
|
134
|
-
self.init
|
135
|
-
filter = filter.map{|k, v| type_convert(k.to_sym, v) }.to_h
|
136
133
|
|
137
|
-
|
138
|
-
|
134
|
+
Menilite.if_server do
|
135
|
+
def fetch(filter: {}, order: nil, includes: nil)
|
136
|
+
self.init
|
137
|
+
store.fetch(self, filter: convert_fileter(filter), order: order, includes: includes)
|
139
138
|
end
|
140
139
|
|
141
|
-
|
142
|
-
|
143
|
-
|
140
|
+
def max(field_name)
|
141
|
+
self.init
|
142
|
+
store.max(self, field_name)
|
144
143
|
end
|
145
144
|
end
|
146
145
|
|
147
|
-
def
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
146
|
+
def find(id)
|
147
|
+
case id
|
148
|
+
when String
|
149
|
+
self[id]
|
150
|
+
when Hash
|
151
|
+
self.fetch(filter:id).first
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def [](id)
|
156
|
+
self.init
|
157
|
+
store.find(self, id)
|
158
|
+
end
|
159
|
+
|
160
|
+
def fetch!(filter: {}, order: nil, includes: nil, &block)
|
161
|
+
raise 'method is block required' unless block_given?
|
162
|
+
|
163
|
+
self.init
|
164
|
+
|
165
|
+
store.fetch!(self, filter: convert_fileter(filter), order: order, includes: includes) do |list|
|
166
|
+
yield list
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def max!(field_name, &block)
|
171
|
+
raise 'method is block required' unless block_given?
|
172
|
+
|
173
|
+
self.init
|
174
|
+
store.max!(self, field_name) do |max|
|
175
|
+
yield max
|
176
|
+
end
|
157
177
|
end
|
158
178
|
|
159
179
|
def store
|
@@ -168,8 +188,6 @@ module Menilite
|
|
168
188
|
subclasses[child] = false
|
169
189
|
end
|
170
190
|
|
171
|
-
FieldInfo = Struct.new(:name, :type, :params)
|
172
|
-
|
173
191
|
def field(name, type = :string, params = {})
|
174
192
|
params.merge!(client: true, server: true)
|
175
193
|
|
@@ -179,44 +197,41 @@ module Menilite
|
|
179
197
|
return unless params[:server]
|
180
198
|
end
|
181
199
|
|
200
|
+
field_info[name] = FieldInfo.new(name, type, params)
|
182
201
|
if type == :reference
|
183
|
-
field_info[
|
184
|
-
else
|
185
|
-
field_info[name] = FieldInfo.new(name, type, params)
|
202
|
+
field_info["#{name}_id".to_sym] = FieldInfo.new("#{name}_id", :id, {})
|
186
203
|
end
|
187
204
|
|
188
205
|
self.instance_eval do
|
189
206
|
if type == :reference
|
190
|
-
|
191
|
-
|
192
|
-
define_method(name) do
|
193
|
-
id = @fields[field_name.to_sym]
|
194
|
-
next nil unless id
|
195
|
-
model_class = Object.const_get(name.to_s.camel_case)
|
196
|
-
model_class[id]
|
207
|
+
define_method("#{name}_id") do
|
208
|
+
@fields[name.to_sym].id
|
197
209
|
end
|
198
210
|
|
199
|
-
define_method(name
|
200
|
-
@fields[
|
211
|
+
define_method("#{name}_id=") do |value|
|
212
|
+
@fields[name.to_sym].load(value)
|
201
213
|
end
|
202
|
-
else
|
203
|
-
field_name = name.to_s
|
204
214
|
end
|
205
215
|
|
206
|
-
define_method(
|
207
|
-
value = @fields[
|
216
|
+
define_method(name) do
|
217
|
+
value = @fields[name.to_sym]
|
208
218
|
if type.is_a?(Hash) && type.keys.first == :enum
|
209
219
|
value = type[:enum][value]
|
210
220
|
end
|
211
221
|
value
|
212
222
|
end
|
213
223
|
|
214
|
-
define_method(
|
224
|
+
define_method("#{name}=") do |value|
|
225
|
+
puts "#{name}=#{value}: #{type}"
|
215
226
|
unless type_validator(type).call(value, name)
|
216
|
-
raise TypeError.new("type error:
|
227
|
+
raise TypeError.new("type error: field name: #{name}, value: #{value}")
|
228
|
+
end
|
229
|
+
if type == :reference
|
230
|
+
@fields[name.to_sym].assign convert_value(type, value)
|
231
|
+
else
|
232
|
+
@fields[name.to_sym] = convert_value(type, value)
|
217
233
|
end
|
218
|
-
|
219
|
-
handle_event(:change, field_name.to_sym, value)
|
234
|
+
handle_event(:change, name.to_sym, value)
|
220
235
|
end
|
221
236
|
end
|
222
237
|
end
|
@@ -248,7 +263,7 @@ module Menilite
|
|
248
263
|
post_data[:model] = model.to_h
|
249
264
|
end
|
250
265
|
|
251
|
-
|
266
|
+
Menilite::Http.post_json(action_url, post_data.to_json) do
|
252
267
|
on :success do |res|
|
253
268
|
callback.call(:success, res) if callback
|
254
269
|
end
|
@@ -283,28 +298,6 @@ module Menilite
|
|
283
298
|
(validators[field_name] ||= []) << Validator.new(self, field_name, &block) if block
|
284
299
|
end
|
285
300
|
|
286
|
-
def find(id)
|
287
|
-
self.init
|
288
|
-
|
289
|
-
case id
|
290
|
-
when String
|
291
|
-
self[id]
|
292
|
-
when Hash
|
293
|
-
self.fetch(filter:id).first
|
294
|
-
end
|
295
|
-
|
296
|
-
end
|
297
|
-
|
298
|
-
def [](id)
|
299
|
-
self.init
|
300
|
-
store.find(self, id)
|
301
|
-
end
|
302
|
-
|
303
|
-
def max(field_name)
|
304
|
-
self.init
|
305
|
-
store.max(self, field_name)
|
306
|
-
end
|
307
|
-
|
308
301
|
def permit(privileges)
|
309
302
|
Menilite.if_server do
|
310
303
|
case privileges
|
@@ -335,6 +328,30 @@ module Menilite
|
|
335
328
|
end
|
336
329
|
end
|
337
330
|
end
|
331
|
+
|
332
|
+
private
|
333
|
+
|
334
|
+
def convert_fileter(filter)
|
335
|
+
converted = filter.map{|k, v| convert_type(k.to_sym, v) }.to_h
|
336
|
+
|
337
|
+
if_server do
|
338
|
+
converted.merge!(privilege_filter)
|
339
|
+
end
|
340
|
+
|
341
|
+
converted
|
342
|
+
end
|
343
|
+
|
344
|
+
def convert_type(key, value)
|
345
|
+
field_info = self.field_info[key] || self.field_info[key.to_s.sub(/_id\z/,'').to_sym]
|
346
|
+
raise "no such field #{key} in #{self}" unless field_info
|
347
|
+
converted = case field_info.type
|
348
|
+
when :boolean
|
349
|
+
value.is_a?(String) ? (value == 'true' ? true : false) : value
|
350
|
+
else
|
351
|
+
value
|
352
|
+
end
|
353
|
+
[key, converted]
|
354
|
+
end
|
338
355
|
end
|
339
356
|
|
340
357
|
def type_validator(type)
|
@@ -356,7 +373,9 @@ module Menilite
|
|
356
373
|
raise TypeError.new("type error")
|
357
374
|
end
|
358
375
|
when :reference
|
359
|
-
-> (value, name) { value.nil? || validate_reference(value, name) }
|
376
|
+
-> (value, name) { client? || value.nil? || validate_reference(value, name) || value.is_a?(Association) }
|
377
|
+
when :id
|
378
|
+
-> (value, name) { value.nil? || value.is_a?(String) }
|
360
379
|
else
|
361
380
|
raise TypeError.new("type error. type: #{type.inspect}")
|
362
381
|
end
|
@@ -389,6 +408,14 @@ module Menilite
|
|
389
408
|
messages.empty? or raise ValidationError.new(messages)
|
390
409
|
end
|
391
410
|
|
411
|
+
def [](key)
|
412
|
+
if self.class.field_info.has_key?(key.to_sym) || self.class.field_info.has_key?("#{key}_id".to_sym)
|
413
|
+
self.send(key)
|
414
|
+
else
|
415
|
+
raise ArgumentError.new("field '#{name}' is not defind")
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
392
419
|
def to_h
|
393
420
|
@fields.merge(id: @guid)
|
394
421
|
end
|
@@ -429,6 +456,12 @@ module Menilite
|
|
429
456
|
end
|
430
457
|
end
|
431
458
|
|
459
|
+
class FieldInfo < Struct.new(:name, :type, :params)
|
460
|
+
def default
|
461
|
+
params[:default] if params.has_key?(:default)
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
432
465
|
class Validator
|
433
466
|
include Menilite::Helper
|
434
467
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Menilite
|
2
|
+
class Model
|
3
|
+
class UnacquiredDataAccess < StandardError; end
|
4
|
+
|
5
|
+
class Association
|
6
|
+
attr_reader :model_class
|
7
|
+
|
8
|
+
def initialize(model_class)
|
9
|
+
@model_class = model_class
|
10
|
+
@model = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def assign(model)
|
14
|
+
@model = model
|
15
|
+
end
|
16
|
+
|
17
|
+
def load(id)
|
18
|
+
assign @model_class.find(id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def id
|
22
|
+
@model && @model.id
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_h
|
26
|
+
raise UnacquiredDataAccess.new unless @model
|
27
|
+
@model.to_h
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def method_missing(method_sym, *args, &block)
|
33
|
+
field_name = method_sym.to_s
|
34
|
+
field_name = field_name[0, field_name.size - 1] if field_name.chars.last == '='
|
35
|
+
field = @model_class.field_info[field_name]
|
36
|
+
if field
|
37
|
+
raise UnacquiredDataAccess.new unless @model
|
38
|
+
@model.send(method_sym, *args)
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -54,13 +54,14 @@ module Menilite
|
|
54
54
|
yield model if block_given?
|
55
55
|
end
|
56
56
|
|
57
|
-
def fetch(model_class, filter: nil, order: nil)
|
57
|
+
def fetch(model_class, filter: nil, order: nil, includes: nil)
|
58
58
|
assoc = @armodels[model_class].all
|
59
59
|
|
60
60
|
assoc = assoc.where(filter_condition(model_class, filter)) if filter
|
61
|
+
assoc = assoc.includes(includes) if includes
|
61
62
|
assoc = assoc.order([order].flatten.map(&:to_sym)) if order
|
62
63
|
|
63
|
-
|
64
|
+
assoc.map {|ar| to_model(ar, model_class) } || []
|
64
65
|
end
|
65
66
|
|
66
67
|
def delete(model_class)
|
@@ -97,6 +98,7 @@ module Menilite
|
|
97
98
|
model.to_h.tap do |hash|
|
98
99
|
references.each do |r|
|
99
100
|
hash["#{r.name}_guid".to_sym] = hash.delete("#{r.name}_id".to_sym)
|
101
|
+
hash.delete(r.name.to_sym)
|
100
102
|
end
|
101
103
|
|
102
104
|
hash[:guid] = hash.delete(:id)
|
@@ -104,7 +106,7 @@ module Menilite
|
|
104
106
|
end
|
105
107
|
|
106
108
|
def fields(ar_obj, model_class)
|
107
|
-
references = model_class.field_info.values.select{|i| i.type == :reference}
|
109
|
+
references = model_class.field_info.values.select{|i| i.type == :reference }
|
108
110
|
ar_obj.attributes.tap do |hash|
|
109
111
|
references.each do |r|
|
110
112
|
hash["#{r.name}_id"] = hash.delete("#{r.name}_guid")
|
@@ -64,6 +64,8 @@ module Menilite
|
|
64
64
|
status 403
|
65
65
|
{ result: 'validation_error', message: e.message, messages: e.messages }.to_json
|
66
66
|
rescue => e
|
67
|
+
puts e.message
|
68
|
+
puts e.backtrace
|
67
69
|
content_type :json
|
68
70
|
status 500
|
69
71
|
{ result: 'error', message: e.message }.to_json
|
@@ -81,8 +83,9 @@ module Menilite
|
|
81
83
|
PrivilegeService.init
|
82
84
|
router.before_action_handlers(klass, 'index').each {|h| self.instance_eval(&h[:proc]) }
|
83
85
|
order = params.delete('order')&.split(?,)
|
84
|
-
|
85
|
-
|
86
|
+
includes = params.delete('includes')
|
87
|
+
data = klass.fetch(filter: params, order: order, includes: includes)
|
88
|
+
json Serializer.serialize(data, includes)
|
86
89
|
end
|
87
90
|
end
|
88
91
|
|
@@ -90,13 +93,15 @@ module Menilite
|
|
90
93
|
with_error_handler do
|
91
94
|
PrivilegeService.init
|
92
95
|
router.before_action_handlers(klass, 'get').each {|h| self.instance_eval(&h[:proc]) }
|
93
|
-
|
96
|
+
includes = params.delete('includes')
|
97
|
+
json Serializer.serialize(klass[params[:id]], includes)
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
97
101
|
post "/#{resource_name}" do
|
98
102
|
PrivilegeService.init
|
99
103
|
router.before_action_handlers(klass, 'post').each {|h| self.instance_eval(&h[:proc]) }
|
104
|
+
includes = params.delete('includes')
|
100
105
|
data = JSON.parse(request.body.read)
|
101
106
|
results = data.map do |model|
|
102
107
|
instance = klass.new model.map{|key, value| [key.to_sym, value] }.to_h
|
@@ -104,7 +109,7 @@ module Menilite
|
|
104
109
|
instance
|
105
110
|
end
|
106
111
|
|
107
|
-
json
|
112
|
+
json Serializer.serialize(results, includes)
|
108
113
|
end
|
109
114
|
|
110
115
|
klass.action_info.each do |name, action|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Menilite
|
2
|
+
module Serializer
|
3
|
+
def self.serialize(obj, includes)
|
4
|
+
case obj
|
5
|
+
when Menilite::Model
|
6
|
+
hash = obj.to_h
|
7
|
+
if includes
|
8
|
+
case includes
|
9
|
+
when String, Symbol
|
10
|
+
hash[includes.to_s] = obj[includes].to_h
|
11
|
+
when Array
|
12
|
+
includes.each do |i|
|
13
|
+
hash[i.to_s] = obj[i].to_h
|
14
|
+
end
|
15
|
+
when Hash
|
16
|
+
includes.each do |k, v|
|
17
|
+
hash[k.to_s] = Menilite::Serializer.serialize(obj[k], v)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
hash
|
22
|
+
when Array
|
23
|
+
obj.map {|o| Menilite::Serializer.serialize(o, includes) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -45,7 +45,7 @@ module Menilite
|
|
45
45
|
yield model if block_given?
|
46
46
|
end
|
47
47
|
|
48
|
-
def fetch(model_class, filter: nil, order: nil)
|
48
|
+
def fetch(model_class, filter: nil, order: nil, includes: nil)
|
49
49
|
File.open filename(model_class) do |file|
|
50
50
|
records = JSON.parse(file.read)
|
51
51
|
records.select! {|r| filter.all? {|k,v| r[k.to_s] == v } } if filter
|
@@ -53,7 +53,11 @@ module Menilite
|
|
53
53
|
@tables[model_class] = records.map {|m| [m["id"], model_class.new(m)] }.to_h
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
@tables[model_class].values || []
|
57
|
+
end
|
58
|
+
|
59
|
+
def fetch!(model_class, filter: nil, order: nil, includes: nil)
|
60
|
+
yield fetch(model_class, filter, order, includes)
|
57
61
|
end
|
58
62
|
|
59
63
|
def delete(model_class)
|
data/lib/menilite/version.rb
CHANGED
data/menilite.gemspec
CHANGED
@@ -21,9 +21,8 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.12"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.0"
|
24
|
-
spec.add_development_dependency 'opal-rspec'
|
24
|
+
spec.add_development_dependency 'opal-rspec'
|
25
25
|
|
26
26
|
spec.add_runtime_dependency "opal"
|
27
|
-
spec.add_runtime_dependency 'opal-browser'
|
28
27
|
spec.add_runtime_dependency "sinatra-activerecord"
|
29
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: menilite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- youchan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -54,26 +54,12 @@ dependencies:
|
|
54
54
|
version: '3.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: opal-rspec
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.5.0
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 0.5.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: opal
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
61
|
version: '0'
|
76
|
-
type: :
|
62
|
+
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
@@ -81,7 +67,7 @@ dependencies:
|
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name: opal
|
70
|
+
name: opal
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - ">="
|
@@ -125,14 +111,18 @@ files:
|
|
125
111
|
- bin/console
|
126
112
|
- bin/setup
|
127
113
|
- lib/menilite.rb
|
114
|
+
- lib/menilite/client/deserializer.rb
|
115
|
+
- lib/menilite/client/http.rb
|
128
116
|
- lib/menilite/client/store.rb
|
129
117
|
- lib/menilite/controller.rb
|
130
118
|
- lib/menilite/helper.rb
|
131
119
|
- lib/menilite/model.rb
|
120
|
+
- lib/menilite/model/association.rb
|
132
121
|
- lib/menilite/server/activerecord_store.rb
|
133
122
|
- lib/menilite/server/error_with_status_code.rb
|
134
123
|
- lib/menilite/server/privilege.rb
|
135
124
|
- lib/menilite/server/router.rb
|
125
|
+
- lib/menilite/server/serializer.rb
|
136
126
|
- lib/menilite/server/store.rb
|
137
127
|
- lib/menilite/version.rb
|
138
128
|
- menilite.gemspec
|
@@ -155,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
145
|
version: '0'
|
156
146
|
requirements: []
|
157
147
|
rubyforge_project:
|
158
|
-
rubygems_version: 2.
|
148
|
+
rubygems_version: 2.6.11
|
159
149
|
signing_key:
|
160
150
|
specification_version: 4
|
161
151
|
summary: Isomorphic models between client side opal and server side ruby.
|