databound 3.0.3 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -6
- data/lib/databound.rb +5 -1
- data/lib/databound/config.rb +1 -1
- data/lib/databound/initializer.rb +11 -0
- data/lib/databound/manager.rb +6 -6
- data/lib/databound/version.rb +1 -1
- data/lib/generators/databound/install/templates/databound-standalone.js +59 -8
- data/spec/controllers/columns_controller_spec.rb +10 -5
- data/spec/controllers/databound_spec.rb +2 -2
- data/spec/controllers/dsl_controller_spec.rb +4 -2
- data/spec/controllers/permit_controller_spec.rb +8 -4
- data/spec/controllers/routes_opts_controller_spec.rb +8 -4
- data/spec/spec_helper.rb +27 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62142f1e789c32e120915d4262dc4f304cd10f1a
|
4
|
+
data.tar.gz: 155cd3e12b5898facaebce3154bfa977b4d248af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37bb7f07e1fd980a94a9173aed4bbcbe8985847beeb25e3ca0a5d920c749337a358d509de015bef840ea0303ba3f0565cbe49a187d68b86eac7df12bdf19dccc
|
7
|
+
data.tar.gz: ac96fcfc5914ea90498701d3ea98e3c39267f6b55c55baf574adb92556a86c677dbd40ac697c87137c9d75e881b1e366772f43c70de5389ffb1e1b2c66b6f0aa
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
[![Gem
|
2
|
-
[![Bower
|
3
|
-
[![
|
4
|
-
[![Code Climate](
|
5
|
-
[![Build Status](
|
1
|
+
[![Gem](https://img.shields.io/gem/v/databound.svg?style=flat-square)](https://rubygems.org/gems/databound)
|
2
|
+
[![Bower](https://img.shields.io/bower/v/databound.svg?style=flat-square)](http://bower.io/search/?q=databound)
|
3
|
+
[![npm](https://img.shields.io/npm/v/databound.svg?style=flat-square)](https://www.npmjs.com/package/databound)
|
4
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/Nedomas/databound-rails.svg?style=flat-square)](https://codeclimate.com/github/Nedomas/databound)
|
5
|
+
[![Build Status](http://img.shields.io/travis/Nedomas/databound-rails.svg?style=flat-square)](https://travis-ci.org/Nedomas/databound)
|
6
6
|
|
7
7
|
![Databound](https://cloud.githubusercontent.com/assets/1877286/4743542/df89dcec-5a28-11e4-9114-6f383fe269cb.png)
|
8
8
|
|
@@ -32,4 +32,4 @@ This repo is for Ruby on Rails backend part of Databound.
|
|
32
32
|
});
|
33
33
|
```
|
34
34
|
|
35
|
-
[
|
35
|
+
[All API docs](http://nedomas.github.io/databound/src/databound.html)
|
data/lib/databound.rb
CHANGED
@@ -11,7 +11,11 @@ require 'databound/rails/routes'
|
|
11
11
|
module Databound
|
12
12
|
def where
|
13
13
|
records = @crud.find_scoped_records
|
14
|
-
|
14
|
+
|
15
|
+
render json: {
|
16
|
+
success: true,
|
17
|
+
records: serialize_array(records),
|
18
|
+
}
|
15
19
|
end
|
16
20
|
|
17
21
|
def create
|
data/lib/databound/config.rb
CHANGED
@@ -7,6 +7,17 @@ module Databound
|
|
7
7
|
send(:define_method, :databound_config) do
|
8
8
|
Databound::Config.new(block, model)
|
9
9
|
end
|
10
|
+
|
11
|
+
if Rails.application.config.consider_all_requests_local
|
12
|
+
rescue_from Databound::NotPermittedError do |exception|
|
13
|
+
render(
|
14
|
+
status: Databound::NotPermittedError::STATUS,
|
15
|
+
json: {
|
16
|
+
message: exception.to_s,
|
17
|
+
},
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
10
21
|
end
|
11
22
|
end
|
12
23
|
end
|
data/lib/databound/manager.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Databound
|
2
|
-
class NotPermittedError < RuntimeError; end
|
2
|
+
class NotPermittedError < RuntimeError; STATUS = 405; end
|
3
|
+
class ConfigError < RuntimeError; end
|
4
|
+
|
3
5
|
class Manager
|
4
6
|
def initialize(controller)
|
5
7
|
@controller = controller
|
@@ -65,9 +67,7 @@ module Databound
|
|
65
67
|
model.where(scope.to_h).where_values.reduce(:and)
|
66
68
|
end
|
67
69
|
|
68
|
-
nodes
|
69
|
-
node.or(memo)
|
70
|
-
end
|
70
|
+
nodes.reduce(:or)
|
71
71
|
end
|
72
72
|
|
73
73
|
def check_params!(action)
|
@@ -119,7 +119,7 @@ module Databound
|
|
119
119
|
elsif activerecord?
|
120
120
|
model.column_names.map(&:to_sym)
|
121
121
|
else
|
122
|
-
raise 'ORM not supported. Use ActiveRecord or Mongoid'
|
122
|
+
raise ConfigError, 'ORM not supported. Use ActiveRecord or Mongoid'
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -132,7 +132,7 @@ module Databound
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def model
|
135
|
-
raise 'No model specified' unless model_name
|
135
|
+
raise ConfigError, 'No model specified' unless model_name
|
136
136
|
|
137
137
|
model_name.to_s.camelize.constantize
|
138
138
|
end
|
data/lib/databound/version.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
var Databound
|
1
|
+
var Databound, DataboundError,
|
2
|
+
__slice = [].slice;
|
2
3
|
|
3
4
|
Databound = (function() {
|
4
5
|
function Databound(endpoint, scope, options) {
|
@@ -27,20 +28,31 @@ Databound = (function() {
|
|
27
28
|
Databound.prototype.where = function(params) {
|
28
29
|
var _this;
|
29
30
|
_this = this;
|
30
|
-
return this.
|
31
|
-
|
31
|
+
return this.wrappedRequest('where', params).then(function(resp) {
|
32
|
+
var records;
|
33
|
+
records = JSON.parse(resp.records).concat(_this.seeds);
|
32
34
|
_this.records = _.sortBy(records, 'id');
|
33
35
|
return _this.promise(_this.records);
|
34
36
|
});
|
35
37
|
};
|
36
38
|
|
39
|
+
Databound.prototype.all = function() {
|
40
|
+
return this.where();
|
41
|
+
};
|
42
|
+
|
37
43
|
Databound.prototype.find = function(id) {
|
38
44
|
var _this;
|
45
|
+
this.checkUndefinedId('find', id);
|
39
46
|
_this = this;
|
40
47
|
return this.where({
|
41
48
|
id: id
|
42
49
|
}).then(function() {
|
43
|
-
|
50
|
+
var record;
|
51
|
+
record = _this.take(id);
|
52
|
+
if (!record) {
|
53
|
+
throw new DataboundError("Couldn't find record with id: " + id);
|
54
|
+
}
|
55
|
+
return _this.promise(record);
|
44
56
|
});
|
45
57
|
};
|
46
58
|
|
@@ -61,6 +73,7 @@ Databound = (function() {
|
|
61
73
|
};
|
62
74
|
|
63
75
|
Databound.prototype.destroy = function(id) {
|
76
|
+
this.checkUndefinedId('destroy', id);
|
64
77
|
return this.requestAndRefresh('destroy', {
|
65
78
|
id: id
|
66
79
|
});
|
@@ -83,11 +96,8 @@ Databound = (function() {
|
|
83
96
|
Databound.prototype.requestAndRefresh = function(action, params) {
|
84
97
|
var _this;
|
85
98
|
_this = this;
|
86
|
-
return this.
|
99
|
+
return this.wrappedRequest(action, params).then(function(resp) {
|
87
100
|
var records, records_with_seeds;
|
88
|
-
if (!(resp != null ? resp.success : void 0)) {
|
89
|
-
throw new Error('Error in the backend');
|
90
|
-
}
|
91
101
|
records = JSON.parse(resp.scoped_records);
|
92
102
|
records_with_seeds = records.concat(_this.seeds);
|
93
103
|
_this.records = _.sortBy(records_with_seeds, 'id');
|
@@ -115,6 +125,47 @@ Databound = (function() {
|
|
115
125
|
};
|
116
126
|
};
|
117
127
|
|
128
|
+
Databound.prototype.wrappedRequest = function() {
|
129
|
+
var args;
|
130
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
131
|
+
return this.request.apply(this, args).then(_.bind(this.handleSuccess, this)).fail(this.handleFailure);
|
132
|
+
};
|
133
|
+
|
134
|
+
Databound.prototype.handleSuccess = function(resp) {
|
135
|
+
if (!(resp != null ? resp.success : void 0)) {
|
136
|
+
throw new Error('Error in the backend');
|
137
|
+
}
|
138
|
+
return this.promise(resp);
|
139
|
+
};
|
140
|
+
|
141
|
+
Databound.prototype.handleFailure = function(e) {
|
142
|
+
if (e.status === DataboundError.STATUS) {
|
143
|
+
throw new DataboundError(e.responseJSON.message);
|
144
|
+
} else {
|
145
|
+
throw new Error("Error in the backend with status " + e.status);
|
146
|
+
}
|
147
|
+
};
|
148
|
+
|
149
|
+
Databound.prototype.checkUndefinedId = function(action, id) {
|
150
|
+
if (!_.isUndefined(id)) {
|
151
|
+
return;
|
152
|
+
}
|
153
|
+
throw new DataboundError("Couldn't " + action + " a record without an id");
|
154
|
+
};
|
155
|
+
|
118
156
|
return Databound;
|
119
157
|
|
120
158
|
})();
|
159
|
+
|
160
|
+
DataboundError = (function() {
|
161
|
+
function DataboundError(text) {
|
162
|
+
this.message = "Databound: " + text;
|
163
|
+
}
|
164
|
+
|
165
|
+
DataboundError.STATUS = 405;
|
166
|
+
|
167
|
+
return DataboundError;
|
168
|
+
|
169
|
+
})();
|
170
|
+
|
171
|
+
DataboundError.prototype = new Error();
|
@@ -10,7 +10,8 @@ describe PostsController, type: :controller do
|
|
10
10
|
scope: {},
|
11
11
|
}
|
12
12
|
|
13
|
-
|
13
|
+
assert_responses(
|
14
|
+
-> { post(:create, javascriptize(data)) },
|
14
15
|
Databound::NotPermittedError,
|
15
16
|
'Request includes unpermitted columns: city',
|
16
17
|
)
|
@@ -39,7 +40,8 @@ describe ColumnsController, type: :controller do
|
|
39
40
|
scope: {},
|
40
41
|
}
|
41
42
|
|
42
|
-
|
43
|
+
assert_responses(
|
44
|
+
-> { post(:create, javascriptize(data)) },
|
43
45
|
Databound::NotPermittedError,
|
44
46
|
'Request includes unpermitted columns: city',
|
45
47
|
)
|
@@ -71,7 +73,8 @@ describe ColumnsController, type: :controller do
|
|
71
73
|
scope: {},
|
72
74
|
}
|
73
75
|
|
74
|
-
|
76
|
+
assert_responses(
|
77
|
+
-> { post(:update, javascriptize(data)) },
|
75
78
|
Databound::NotPermittedError,
|
76
79
|
'Request includes unpermitted columns: city',
|
77
80
|
)
|
@@ -100,7 +103,8 @@ describe ColumnsController, type: :controller do
|
|
100
103
|
scope: { city: 'Barcelona' },
|
101
104
|
}
|
102
105
|
|
103
|
-
|
106
|
+
assert_responses(
|
107
|
+
-> { post(:create, javascriptize(data)) },
|
104
108
|
Databound::NotPermittedError,
|
105
109
|
'Request includes unpermitted columns: city',
|
106
110
|
)
|
@@ -117,7 +121,8 @@ describe ColumnsController, type: :controller do
|
|
117
121
|
scope: { city: 'Barcelona' },
|
118
122
|
}
|
119
123
|
|
120
|
-
|
124
|
+
assert_responses(
|
125
|
+
-> { post(:update, javascriptize(data)) },
|
121
126
|
Databound::NotPermittedError,
|
122
127
|
'Request includes unpermitted columns: city',
|
123
128
|
)
|
@@ -44,7 +44,7 @@ describe UsersController, type: :controller do
|
|
44
44
|
}
|
45
45
|
|
46
46
|
post(:where, javascriptize(data))
|
47
|
-
expect(rubize(response)).to eq([])
|
47
|
+
expect(rubize(response)).to eq(success: true, records: [])
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'respond with correct records' do
|
@@ -56,7 +56,7 @@ describe UsersController, type: :controller do
|
|
56
56
|
}
|
57
57
|
|
58
58
|
post(:where, javascriptize(data))
|
59
|
-
expect(gather(:name, response)).to eq(%w(John Peter))
|
59
|
+
expect(gather(:records, :name, response)).to eq(%w(John Peter))
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -80,7 +80,8 @@ describe DslController, type: :controller do
|
|
80
80
|
scope: {},
|
81
81
|
}
|
82
82
|
|
83
|
-
|
83
|
+
assert_responses(
|
84
|
+
-> { post(:create, javascriptize(data)) },
|
84
85
|
Databound::NotPermittedError,
|
85
86
|
"DSL column 'city' received unmatched string 'New York'." \
|
86
87
|
" Use 'strict: false' in DSL definition to allow everything.",
|
@@ -176,7 +177,8 @@ describe DslController, type: :controller do
|
|
176
177
|
scope: {},
|
177
178
|
}
|
178
179
|
|
179
|
-
|
180
|
+
assert_responses(
|
181
|
+
-> { post(:create, javascriptize(data)) },
|
180
182
|
Databound::NotPermittedError,
|
181
183
|
"DSL column 'city' received unmatched string 'New York'." \
|
182
184
|
" Use 'strict: false' in DSL definition to allow everything.",
|
@@ -18,7 +18,8 @@ describe PermitController, type: :controller do
|
|
18
18
|
scope: {},
|
19
19
|
}
|
20
20
|
|
21
|
-
|
21
|
+
assert_responses(
|
22
|
+
-> { post(:where, javascriptize(data)) },
|
22
23
|
Databound::NotPermittedError,
|
23
24
|
'Request for read not permitted',
|
24
25
|
)
|
@@ -47,7 +48,8 @@ describe PermitController, type: :controller do
|
|
47
48
|
scope: {},
|
48
49
|
}
|
49
50
|
|
50
|
-
|
51
|
+
assert_responses(
|
52
|
+
-> { post(:create, javascriptize(data)) },
|
51
53
|
Databound::NotPermittedError,
|
52
54
|
'Request for create not permitted',
|
53
55
|
)
|
@@ -76,7 +78,8 @@ describe PermitController, type: :controller do
|
|
76
78
|
scope: {},
|
77
79
|
}
|
78
80
|
|
79
|
-
|
81
|
+
assert_responses(
|
82
|
+
-> { post(:update, javascriptize(data)) },
|
80
83
|
Databound::NotPermittedError,
|
81
84
|
'Request for update not permitted',
|
82
85
|
)
|
@@ -104,7 +107,8 @@ describe PermitController, type: :controller do
|
|
104
107
|
scope: {},
|
105
108
|
}
|
106
109
|
|
107
|
-
|
110
|
+
assert_responses(
|
111
|
+
-> { post(:destroy, javascriptize(data)) },
|
108
112
|
Databound::NotPermittedError,
|
109
113
|
'Request for destroy not permitted',
|
110
114
|
)
|
@@ -10,7 +10,8 @@ describe PostsController, type: :controller do
|
|
10
10
|
scope: {},
|
11
11
|
}
|
12
12
|
|
13
|
-
|
13
|
+
assert_responses(
|
14
|
+
-> { post(:create, javascriptize(data)) },
|
14
15
|
Databound::NotPermittedError,
|
15
16
|
'Request includes unpermitted columns: description',
|
16
17
|
)
|
@@ -42,7 +43,8 @@ describe PostsController, type: :controller do
|
|
42
43
|
scope: {},
|
43
44
|
}
|
44
45
|
|
45
|
-
|
46
|
+
assert_responses(
|
47
|
+
-> { post(:update, javascriptize(data)) },
|
46
48
|
Databound::NotPermittedError,
|
47
49
|
'Request includes unpermitted columns: description',
|
48
50
|
)
|
@@ -71,7 +73,8 @@ describe PostsController, type: :controller do
|
|
71
73
|
scope: { description: 'Barcelona' },
|
72
74
|
}
|
73
75
|
|
74
|
-
|
76
|
+
assert_responses(
|
77
|
+
-> { post(:create, javascriptize(data)) },
|
75
78
|
Databound::NotPermittedError,
|
76
79
|
'Request includes unpermitted columns: description',
|
77
80
|
)
|
@@ -88,7 +91,8 @@ describe PostsController, type: :controller do
|
|
88
91
|
scope: { description: 'Barcelona 2' },
|
89
92
|
}
|
90
93
|
|
91
|
-
|
94
|
+
assert_responses(
|
95
|
+
-> { post(:update, javascriptize(data)) },
|
92
96
|
Databound::NotPermittedError,
|
93
97
|
'Request includes unpermitted columns: description',
|
94
98
|
)
|
data/spec/spec_helper.rb
CHANGED
@@ -18,7 +18,7 @@ def javascriptize(ruby_obj)
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def rubize(response)
|
21
|
-
|
21
|
+
convert_records(optionize(JSON.parse(response.body)))
|
22
22
|
end
|
23
23
|
|
24
24
|
def optionize(obj)
|
@@ -30,22 +30,38 @@ def optionize(obj)
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
return
|
35
|
-
result = obj
|
33
|
+
def convert_records(data)
|
34
|
+
return data unless data.is_a?(Hash)
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
end
|
36
|
+
%i(records scoped_records).each_with_object(data) do |type, obj|
|
37
|
+
next unless data[type]
|
40
38
|
|
41
|
-
|
42
|
-
|
39
|
+
obj[type] = JSON.parse(data[type]).map do |r|
|
40
|
+
r.except('created_at', 'updated_at')
|
41
|
+
end
|
42
|
+
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def gather(attribute, response)
|
46
|
-
rubize(response).map { |record| record[attribute] }
|
45
|
+
def gather(collection, attribute, response)
|
46
|
+
rubize(response)[collection].map { |record| record.to_options[attribute] }
|
47
47
|
end
|
48
48
|
|
49
49
|
def all_records(model = User)
|
50
50
|
model.select(:id, :name, :city).map(&:attributes)
|
51
51
|
end
|
52
|
+
|
53
|
+
def assert_responses(code, error, msg)
|
54
|
+
friendly_handler = controller.class.rescue_handlers.first.last
|
55
|
+
|
56
|
+
controller.class.rescue_from(error) { raise error, msg }
|
57
|
+
expect(code).to raise_error(error, msg)
|
58
|
+
|
59
|
+
# check friendly handler
|
60
|
+
controller.class.rescue_from(error, with: friendly_handler)
|
61
|
+
code.call
|
62
|
+
|
63
|
+
expect(response.status).to eq(error::STATUS)
|
64
|
+
expect(rubize(response)).to eq(
|
65
|
+
message: msg,
|
66
|
+
)
|
67
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: databound
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Domas Bitvinskas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec-rails
|