introspective_grape 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +14 -5
- data/.travis.yml +38 -12
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -1
- data/gemfiles/2.0.0-Gemfile +3 -3
- data/gemfiles/2.2.0-Gemfile +21 -0
- data/gemfiles/Gemfile.rails.3.2.22 +13 -0
- data/gemfiles/Gemfile.rails.4.1.13 +13 -0
- data/gemfiles/Gemfile.rails.4.2.7.1 +13 -0
- data/gemfiles/Gemfile.rails.4.2.7.1.new.swagger +12 -0
- data/gemfiles/Gemfile.rails.5.0.1 +13 -0
- data/gemfiles/Gemfile.rails.master +13 -0
- data/introspective_grape.gemspec +2 -3
- data/lib/introspective_grape/api.rb +20 -23
- data/lib/introspective_grape/camel_snake.rb +1 -1
- data/lib/introspective_grape/create_helpers.rb +22 -0
- data/lib/introspective_grape/filters.rb +17 -12
- data/lib/introspective_grape/traversal.rb +1 -1
- data/lib/introspective_grape/version.rb +1 -1
- data/lib/introspective_grape.rb +7 -6
- data/spec/dummy/Gemfile +6 -7
- data/spec/dummy/app/api/dummy/location_api.rb +2 -1
- data/spec/dummy/app/api/dummy/user_api.rb +3 -2
- data/spec/dummy/app/api/dummy_api.rb +0 -1
- data/spec/dummy/app/models/image.rb +3 -0
- data/spec/dummy/app/models/role.rb +2 -7
- data/spec/dummy/app/models/user.rb +2 -2
- data/spec/dummy/config/application.rb +2 -3
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/config/environments/production.rb +1 -1
- data/spec/dummy/config/environments/test.rb +1 -0
- data/spec/dummy/config/initializers/assets.rb +1 -1
- data/spec/dummy/config/initializers/devise.rb +1 -1
- data/spec/dummy/config/initializers/devise_async.rb +1 -1
- data/spec/dummy/db/migrate/20141002205024_devise_create_users.rb +4 -2
- data/spec/dummy/db/migrate/20141002211055_devise_create_admin_users.rb +2 -2
- data/spec/dummy/db/schema.rb +1 -0
- data/spec/models/role_spec.rb +1 -7
- data/spec/models/user_spec.rb +4 -4
- data/spec/requests/project_api_spec.rb +2 -2
- data/spec/requests/role_api_spec.rb +6 -5
- data/spec/requests/user_api_spec.rb +12 -2
- metadata +10 -38
- data/spec/dummy/app/models/super_user.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0478e58629bddd63190fa37d11c63c07872b59b
|
4
|
+
data.tar.gz: 5176e6bfb35d31a20ad541a8e7069c365fb18f8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b45bc43f714cf140f1f2903fb075290e209b08f99f32ed656639c49440949c7de5b58ae9dded52af1aff3087690bf8e6e9591e65c2edd122914c82dd1113320f
|
7
|
+
data.tar.gz: 9ec43d28db3b0b6a79970270508c636629626800d3438fe2deb56b180cfd2f8ab0a59a7b52f0d86b73a1e62559716d56f1a72a8557eea779066a69589d4d68c7
|
data/.rubocop.yml
CHANGED
@@ -536,10 +536,10 @@ Style/DefWithParentheses:
|
|
536
536
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#method-parens'
|
537
537
|
Enabled: false
|
538
538
|
|
539
|
-
Style/DeprecatedHashMethods:
|
540
|
-
Description: 'Checks for use of deprecated Hash methods.'
|
541
|
-
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-key'
|
542
|
-
Enabled: false
|
539
|
+
#Style/DeprecatedHashMethods:
|
540
|
+
# Description: 'Checks for use of deprecated Hash methods.'
|
541
|
+
# StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#hash-key'
|
542
|
+
# Enabled: false
|
543
543
|
|
544
544
|
Style/Documentation:
|
545
545
|
Description: 'Document classes and non-namespace modules.'
|
@@ -724,7 +724,7 @@ Style/LineEndConcatenation:
|
|
724
724
|
line end.
|
725
725
|
Enabled: false
|
726
726
|
|
727
|
-
Style/
|
727
|
+
Style/MethodCallWithoutArgsParentheses:
|
728
728
|
Description: 'Do not use parentheses for method calls with no arguments.'
|
729
729
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#no-args-no-parens'
|
730
730
|
Enabled: false
|
@@ -810,6 +810,10 @@ Style/Not:
|
|
810
810
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#bang-not-not'
|
811
811
|
Enabled: false
|
812
812
|
|
813
|
+
Style/NumericPredicate:
|
814
|
+
Exclude:
|
815
|
+
- 'spec/**/*'
|
816
|
+
|
813
817
|
Style/NumericLiterals:
|
814
818
|
Description: >-
|
815
819
|
Add underscores to large numeric literals to improve their
|
@@ -1162,3 +1166,8 @@ Style/WordArray:
|
|
1162
1166
|
Description: 'Use %w or %W for arrays of words.'
|
1163
1167
|
StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-w'
|
1164
1168
|
Enabled: false
|
1169
|
+
|
1170
|
+
Style/BlockLength:
|
1171
|
+
Exclude:
|
1172
|
+
- '*.gemspec'
|
1173
|
+
- 'spec/**/*'
|
data/.travis.yml
CHANGED
@@ -7,33 +7,59 @@ script:
|
|
7
7
|
- bundle exec rspec
|
8
8
|
|
9
9
|
rvm:
|
10
|
+
- 2.0.0
|
11
|
+
- 2.1.0
|
12
|
+
- 2.2.0
|
10
13
|
- 2.3.0
|
11
14
|
- 2.2.6
|
12
15
|
- ruby-head
|
13
16
|
- jruby-head
|
17
|
+
gemfile:
|
18
|
+
# - gemfiles/Gemfile.rails.3.2.22
|
19
|
+
#- gemfiles/Gemfile.rails.4.1.13
|
20
|
+
- gemfiles/Gemfile.rails.4.2.7.1
|
21
|
+
- gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
22
|
+
- gemfiles/Gemfile.rails.5.0.1
|
23
|
+
- gemfiles/Gemfile.rails.master
|
24
|
+
|
14
25
|
matrix:
|
15
|
-
|
26
|
+
exclude:
|
16
27
|
# We'll have to back up to grape-swagger 0.11 for earlier rubies.
|
17
28
|
- rvm: 2.0.0
|
18
|
-
gemfile: gemfiles/2.
|
29
|
+
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
30
|
+
- rvm: 2.0.0
|
31
|
+
gemfile: gemfiles/Gemfile.rails.5.0.1
|
32
|
+
- rvm: 2.0.0
|
33
|
+
gemfile: gemfiles/Gemfile.rails.master
|
34
|
+
- rvm: 2.1.0
|
35
|
+
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
36
|
+
- rvm: 2.1.0
|
37
|
+
gemfile: gemfiles/Gemfile.rails.5.0.1
|
19
38
|
- rvm: 2.1.0
|
20
|
-
gemfile: gemfiles/
|
39
|
+
gemfile: gemfiles/Gemfile.rails.master
|
21
40
|
- rvm: 2.2.0
|
22
|
-
gemfile: gemfiles/2.
|
41
|
+
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
42
|
+
- rvm: 2.2.0
|
43
|
+
gemfile: gemfiles/Gemfile.rails.5.0.1
|
44
|
+
- rvm: 2.2.0
|
45
|
+
gemfile: gemfiles/Gemfile.rails.master
|
23
46
|
- rvm: jruby-9.0.4.0
|
24
|
-
gemfile: gemfiles/2.
|
25
|
-
|
47
|
+
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
48
|
+
- rvm: jruby-9.0.4.0
|
49
|
+
gemfile: gemfiles/Gemfile.rails.5.0.1
|
50
|
+
- rvm: jruby-9.0.4.0
|
51
|
+
gemfile: gemfiles/Gemfile.rails.master
|
26
52
|
allow_failures:
|
27
53
|
- rvm: ruby-head
|
28
54
|
- rvm: jruby-head
|
29
55
|
|
30
56
|
env:
|
31
|
-
matrix:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
57
|
+
#matrix:
|
58
|
+
# - RAILS=3.2.22
|
59
|
+
# - RAILS=4.1.13
|
60
|
+
# - RAILS=4.2.5.1
|
61
|
+
# - RAILS=5.0.1
|
62
|
+
# - RAILS=master
|
37
63
|
global:
|
38
64
|
- JRUBY_OPTS="-J-Xmx1024m --debug"
|
39
65
|
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/gemfiles/2.0.0-Gemfile
CHANGED
@@ -6,9 +6,9 @@ source 'https://rubygems.org'
|
|
6
6
|
|
7
7
|
gemspec :path => '../'
|
8
8
|
|
9
|
-
gem 'grape', '0.
|
10
|
-
gem 'grape-swagger', '
|
11
|
-
gem 'nokogiri', '
|
9
|
+
gem 'grape', '< 0.17'
|
10
|
+
gem 'grape-swagger', '< 0.12.0'
|
11
|
+
gem 'nokogiri', '< 1.6.9'
|
12
12
|
gem 'coveralls', require: false
|
13
13
|
|
14
14
|
# Declare any dependencies that are still in development here instead of in
|
@@ -0,0 +1,21 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Declare your gem's dependencies in introspective_grape.gemspec.
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
5
|
+
# development dependencies will be added by default to the :development group.
|
6
|
+
|
7
|
+
gemspec :path => '../'
|
8
|
+
|
9
|
+
gem 'grape'
|
10
|
+
gem 'grape-swagger'
|
11
|
+
gem 'coveralls', require: false
|
12
|
+
|
13
|
+
#
|
14
|
+
# Declare any dependencies that are still in development here instead of in
|
15
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
16
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
17
|
+
# your gem to rubygems.org.
|
18
|
+
|
19
|
+
group :development do
|
20
|
+
# gem 'byebug'
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec :path => '../'
|
4
|
+
|
5
|
+
gem 'rails', '3.2.22'
|
6
|
+
gem 'grape', '< 0.17'
|
7
|
+
gem 'grape-swagger', '< 0.12.0'
|
8
|
+
gem 'nokogiri', '< 1.6.9'
|
9
|
+
gem 'coveralls', require: false
|
10
|
+
|
11
|
+
group :development,:test do
|
12
|
+
gem 'rspec'
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec :path => '../'
|
4
|
+
|
5
|
+
gem 'rails', '4.1.13'
|
6
|
+
gem 'grape', '< 0.17'
|
7
|
+
gem 'grape-swagger', '< 0.12.0'
|
8
|
+
gem 'nokogiri', '< 1.6.9'
|
9
|
+
gem 'coveralls', require: false
|
10
|
+
|
11
|
+
group :development,:test do
|
12
|
+
gem 'rspec'
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec :path => '../'
|
4
|
+
|
5
|
+
gem 'rails', '4.2.7.1'
|
6
|
+
gem 'grape', '< 0.17'
|
7
|
+
gem 'grape-swagger', '< 0.12.0'
|
8
|
+
gem 'nokogiri', '< 1.6.9'
|
9
|
+
gem 'coveralls', require: false
|
10
|
+
|
11
|
+
group :development,:test do
|
12
|
+
gem 'rspec'
|
13
|
+
end
|
data/introspective_grape.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
|
21
21
|
s.required_ruby_version = '~> 2.0'
|
22
22
|
|
23
|
-
s.add_dependency "rails", '>= 3.0.0'
|
23
|
+
s.add_dependency "rails", '>= 3.0.0'
|
24
24
|
|
25
25
|
s.add_dependency 'grape' #, '~> 0.16.2'
|
26
26
|
s.add_dependency 'grape-entity' #, '< 0.5.0'
|
@@ -40,11 +40,10 @@ Gem::Specification.new do |s|
|
|
40
40
|
#s.add_development_dependency "byebug"
|
41
41
|
s.add_development_dependency "rspec-rails", '>= 3.0'
|
42
42
|
s.add_development_dependency 'devise'
|
43
|
-
s.add_development_dependency 'devise-async'
|
43
|
+
#s.add_development_dependency 'devise-async'
|
44
44
|
s.add_development_dependency 'paperclip', '< 5.0'
|
45
45
|
s.add_development_dependency 'machinist'
|
46
46
|
s.add_development_dependency 'simplecov'
|
47
47
|
s.add_development_dependency 'rufus-mnemo'
|
48
|
-
s.add_development_dependency "activerecord-tableless", "~> 1.0"
|
49
48
|
|
50
49
|
end
|
@@ -8,6 +8,7 @@ end
|
|
8
8
|
module IntrospectiveGrape
|
9
9
|
class API < Grape::API
|
10
10
|
extend IntrospectiveGrape::Helpers
|
11
|
+
extend IntrospectiveGrape::CreateHelpers
|
11
12
|
extend IntrospectiveGrape::Filters
|
12
13
|
extend IntrospectiveGrape::Traversal
|
13
14
|
extend IntrospectiveGrape::Doc
|
@@ -56,16 +57,18 @@ module IntrospectiveGrape
|
|
56
57
|
self.send(IntrospectiveGrape::API.authentication_method(self))
|
57
58
|
end
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
if IntrospectiveGrape.config.camelize_parameters
|
61
|
+
child.before_validation do
|
62
|
+
# We have to snake case the Rack params then re-assign @params to the
|
63
|
+
# request.params, because of the I-think-very-goofy-and-inexplicable
|
64
|
+
# way Grape interacts with both independently of each other
|
65
|
+
(params.try(:with_snake_keys)||{}).each do |k,v|
|
66
|
+
request.delete_param(k.camelize(:lower))
|
67
|
+
request.update_param(k, v)
|
68
|
+
end
|
69
|
+
@params = request.params
|
66
70
|
end
|
67
|
-
|
68
|
-
end if IntrospectiveGrape.config.camelize_parameters
|
71
|
+
end
|
69
72
|
end
|
70
73
|
|
71
74
|
# We will probably need before and after hooks eventually, but haven't yet...
|
@@ -183,8 +186,9 @@ module IntrospectiveGrape
|
|
183
186
|
records = policy_scope( root.model.includes(klass.default_includes(root.model)) )
|
184
187
|
|
185
188
|
records = klass.apply_filter_params(klass, model, api_params, params, records)
|
186
|
-
|
189
|
+
|
187
190
|
records = records.map{|r| klass.find_leaves( routes, r, params ) }.flatten.compact.uniq
|
191
|
+
|
188
192
|
# paginate the records using Kaminari
|
189
193
|
records = paginate(Kaminari.paginate_array(records)) if klass.pagination
|
190
194
|
present records, with: "#{klass}::#{model}Entity".constantize
|
@@ -206,7 +210,6 @@ module IntrospectiveGrape
|
|
206
210
|
def define_create(dsl, routes, model, api_params)
|
207
211
|
name = routes.last.name.singularize
|
208
212
|
klass = routes.first.klass
|
209
|
-
root = routes.first
|
210
213
|
dsl.desc "create a #{name}" do
|
211
214
|
detail klass.create_documentation || "creates a new #{name} record"
|
212
215
|
end
|
@@ -214,14 +217,8 @@ module IntrospectiveGrape
|
|
214
217
|
klass.generate_params(self, :create, model, api_params, true)
|
215
218
|
end
|
216
219
|
dsl.post do
|
217
|
-
|
218
|
-
|
219
|
-
else
|
220
|
-
@model = root.model.new( safe_params(params).permit(klass.whitelist) )
|
221
|
-
end
|
222
|
-
authorize @model, :create?
|
223
|
-
@model.save!
|
224
|
-
present klass.find_leaves(routes, @model.reload, params), with: "#{klass}::#{model}Entity".constantize
|
220
|
+
representation = @model ? klass.add_new_records_to_root_record(self, routes, params, @model) : klass.create_new_record(self, routes, params)
|
221
|
+
present representation, with: "#{klass}::#{model}Entity".constantize
|
225
222
|
end
|
226
223
|
end
|
227
224
|
|
@@ -333,7 +330,7 @@ module IntrospectiveGrape
|
|
333
330
|
# model : The ActiveRecord model class
|
334
331
|
# fields: The whitelisted data structure for Rails' strong params, from which we
|
335
332
|
# infer Grape's parameters
|
336
|
-
|
333
|
+
|
337
334
|
# skip the ID param at the root level endpoint, so we don't duplicate the URL parameter (api/v#/model/modelId)
|
338
335
|
fields -= [:id] if is_root_endpoint
|
339
336
|
|
@@ -403,7 +400,7 @@ module IntrospectiveGrape
|
|
403
400
|
# Check if it's a file attachment, look for an override class from the model,
|
404
401
|
# check Pg2Ruby, use the database type, or fail over to a String:
|
405
402
|
( is_file_attachment?(model,f) && Rack::Multipart::UploadedFile ) ||
|
406
|
-
(model.try(:grape_param_types)||{}).with_indifferent_access[f]
|
403
|
+
(model.try(:grape_param_types)||{}).with_indifferent_access[f] ||
|
407
404
|
Pg2Ruby[db_type] ||
|
408
405
|
begin db_type.to_s.camelize.constantize rescue nil end ||
|
409
406
|
String
|
@@ -411,9 +408,9 @@ module IntrospectiveGrape
|
|
411
408
|
|
412
409
|
def param_required?(model,f)
|
413
410
|
# Detect if the field is a required field for the create action
|
414
|
-
return false if skip_presence_validations.include?
|
411
|
+
return false if skip_presence_validations.include?(f)
|
415
412
|
|
416
|
-
validated_field =
|
413
|
+
validated_field = f =~ /_id/ ? f.to_s.sub(/_id\z/,'').to_sym : f.to_sym
|
417
414
|
|
418
415
|
model.validators_on(validated_field).any? {|v| v.kind_of? ActiveRecord::Validations::PresenceValidator }
|
419
416
|
end
|
@@ -29,7 +29,7 @@ if IntrospectiveGrape.config.camelize_parameters
|
|
29
29
|
alias_method_chain :create_documentation_class, :camelized
|
30
30
|
end
|
31
31
|
end
|
32
|
-
else
|
32
|
+
else
|
33
33
|
module GrapeSwagger
|
34
34
|
module DocMethods
|
35
35
|
def self.extended(mod)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module IntrospectiveGrape
|
2
|
+
module CreateHelpers
|
3
|
+
|
4
|
+
def add_new_records_to_root_record(dsl, routes, params, model)
|
5
|
+
dsl.authorize model, :create?
|
6
|
+
ActiveRecord::Base.transaction do
|
7
|
+
old = find_leaves(routes, model, params)
|
8
|
+
model.update_attributes( dsl.send(:safe_params,params).permit(whitelist) )
|
9
|
+
new = find_leaves(routes, model, params)
|
10
|
+
old.respond_to?(:size) ? new-old : new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_new_record(dsl, routes, params)
|
15
|
+
model = routes.first.model.new( dsl.send(:safe_params,params).permit(whitelist) )
|
16
|
+
dsl.authorize model, :create?
|
17
|
+
model.save!
|
18
|
+
find_leaves(routes, model.reload, params)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -72,30 +72,33 @@ module IntrospectiveGrape::Filters
|
|
72
72
|
end
|
73
73
|
|
74
74
|
dsl.optional :filter, type: String, description: "JSON of conditions for query. If you're familiar with ActiveRecord's query conventions you can build more complex filters, e.g. against included child associations, e.g. {\"<association_name>_<parent>\":{\"field\":\"value\"}}" if filters.include?(:all) || filters.include?(:filter)
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def apply_simple_filter(klass, model, params, records, field)
|
79
|
+
return records if params[field].blank?
|
75
80
|
|
81
|
+
if timestamp_filter(klass,model,field)
|
82
|
+
op = field.ends_with?("_start") ? ">=" : "<="
|
83
|
+
records.where("#{timestamp_filter(klass,model,field)} #{op} ?", Time.zone.parse(params[field]))
|
84
|
+
elsif model.respond_to?("#{field}=")
|
85
|
+
records.send("#{field}=", params[field])
|
86
|
+
else
|
87
|
+
records.where(field => params[field])
|
88
|
+
end
|
76
89
|
end
|
77
90
|
|
78
91
|
def apply_filter_params(klass, model, api_params, params, records)
|
79
92
|
records = records.order(default_sort) if default_sort.present?
|
80
93
|
|
81
94
|
simple_filters(klass, model, api_params).each do |field|
|
82
|
-
|
83
|
-
|
84
|
-
if timestamp_filter(klass,model,field)
|
85
|
-
op = field.ends_with?("_start") ? ">=" : "<="
|
86
|
-
records = records.where("#{timestamp_filter(klass,model,field)} #{op} ?", Time.zone.parse(params[field]))
|
87
|
-
elsif model.respond_to?("#{field}=")
|
88
|
-
records = records.send("#{field}=", params[field])
|
89
|
-
else
|
90
|
-
records = records.where(field => params[field])
|
91
|
-
end
|
95
|
+
records = apply_simple_filter(klass, model, params, records, field)
|
92
96
|
end
|
93
97
|
|
94
|
-
klass.custom_filters.each do |filter,
|
98
|
+
klass.custom_filters.each do |filter,_details|
|
95
99
|
records = records.send(filter, params[filter])
|
96
100
|
end
|
97
101
|
|
98
|
-
|
99
102
|
if params[:filter].present?
|
100
103
|
filters = JSON.parse( params[:filter].delete('\\') )
|
101
104
|
filters.each do |key, value|
|
@@ -103,6 +106,8 @@ module IntrospectiveGrape::Filters
|
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
109
|
+
records.where( JSON.parse(params[:query]) ) if params[:query].present?
|
110
|
+
|
106
111
|
records
|
107
112
|
end
|
108
113
|
end
|
@@ -33,7 +33,7 @@ module IntrospectiveGrape::Traversal
|
|
33
33
|
return record unless routes.size > 1
|
34
34
|
# For deeply nested routes we need to search from the root of the API to the leaf
|
35
35
|
# of its nested associations in order to guarantee the validity of the relationship,
|
36
|
-
# the authorization on the parent model, and the sanity of passed parameters.
|
36
|
+
# the authorization on the parent model, and the sanity of passed parameters.
|
37
37
|
routes[1..-1].each_with_index do |r|
|
38
38
|
if record && params[r.key]
|
39
39
|
ref = r.reflection
|
data/lib/introspective_grape.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module IntrospectiveGrape
|
2
|
-
autoload :API,
|
3
|
-
autoload :CamelSnake,
|
4
|
-
autoload :
|
5
|
-
autoload :
|
6
|
-
autoload :
|
7
|
-
autoload :
|
2
|
+
autoload :API, 'introspective_grape/api'
|
3
|
+
autoload :CamelSnake, 'introspective_grape/camel_snake'
|
4
|
+
autoload :CreateHelpers, 'introspective_grape/create_helpers'
|
5
|
+
autoload :Doc, 'introspective_grape/doc'
|
6
|
+
autoload :Filters, 'introspective_grape/filters'
|
7
|
+
autoload :Helpers, 'introspective_grape/helpers'
|
8
|
+
autoload :Traversal, 'introspective_grape/traversal'
|
8
9
|
|
9
10
|
module Formatter
|
10
11
|
autoload :CamelJson, 'introspective_grape/formatter/camel_json'
|
data/spec/dummy/Gemfile
CHANGED
@@ -2,18 +2,17 @@ source 'https://rubygems.org'
|
|
2
2
|
gem 'rails', '<5.0'
|
3
3
|
|
4
4
|
#gem 'byebug'
|
5
|
+
gem 'camel_snake_keys'
|
6
|
+
|
7
|
+
gem 'delayed_paperclip'
|
8
|
+
#gem 'devise-async'
|
5
9
|
|
6
10
|
gem 'grape'
|
7
11
|
gem 'grape-entity'
|
8
|
-
gem 'grape-swagger'
|
9
12
|
gem 'grape-kaminari'
|
13
|
+
gem 'grape-swagger'
|
10
14
|
|
11
|
-
gem 'pundit'
|
12
15
|
gem 'paperclip'
|
13
|
-
gem '
|
14
|
-
gem 'devise-async'
|
15
|
-
gem 'activerecord-tableless'
|
16
|
-
|
17
|
-
gem 'camel_snake_keys'
|
16
|
+
gem 'pundit'
|
18
17
|
|
19
18
|
gem 'sqlite3'
|
@@ -7,7 +7,8 @@ class Dummy::LocationAPI < IntrospectiveGrape::API
|
|
7
7
|
|
8
8
|
filter_on :name, :filter
|
9
9
|
|
10
|
-
restful Location, [
|
10
|
+
restful Location, [
|
11
|
+
:name, :kind,
|
11
12
|
{gps_attributes: [:id, :lat, :lng, :alt, :_destroy]},
|
12
13
|
{beacons_attributes: [:id, :company_id, :mac_address, :uuid, :major, :minor, :_destroy]},
|
13
14
|
]
|
@@ -8,7 +8,8 @@ class Dummy::UserAPI < IntrospectiveGrape::API
|
|
8
8
|
|
9
9
|
filter_on :all
|
10
10
|
|
11
|
-
restful User, [
|
11
|
+
restful User, [
|
12
|
+
:id, :email, :password, :first_name, :last_name, :skip_confirmation_email,
|
12
13
|
:created_at, :updated_at,
|
13
14
|
user_project_jobs_attributes: [:id, :job_id, :project_id, :_destroy],
|
14
15
|
roles_attributes: [:id, :ownable_type, :ownable_id, :_destroy],
|
@@ -20,7 +21,7 @@ class Dummy::UserAPI < IntrospectiveGrape::API
|
|
20
21
|
end
|
21
22
|
|
22
23
|
class ImageEntity < Grape::Entity
|
23
|
-
expose :id, :file_processing
|
24
|
+
expose :id, :file_processing, :medium_url
|
24
25
|
end
|
25
26
|
|
26
27
|
class UserProjectJobEntity < Grape::Entity
|
@@ -9,6 +9,9 @@ class Image < ActiveRecord::Base
|
|
9
9
|
validates_attachment :file, content_type: {content_type: ["image/jpeg", "image/png", "image/gif"]}
|
10
10
|
validates_attachment_size :file, :less_than => 2.megabytes
|
11
11
|
|
12
|
+
def medium_url
|
13
|
+
file.url(:medium)
|
14
|
+
end
|
12
15
|
#process_in_background :file, processing_image_url: 'empty_avatar.png'
|
13
16
|
|
14
17
|
Paperclip.interpolates :imageable_type do |attachment, _style|
|
@@ -3,7 +3,7 @@ class Role < AbstractAdapter
|
|
3
3
|
belongs_to :ownable, polymorphic: true
|
4
4
|
|
5
5
|
validates_uniqueness_of :user_id, scope: [:ownable_type,:ownable_id], unless: "user_id.nil?", message: "user has already been assigned that role"
|
6
|
-
OWNABLE_TYPES = %w(
|
6
|
+
OWNABLE_TYPES = %w(Company Project).freeze
|
7
7
|
validates_inclusion_of :ownable_type, in: OWNABLE_TYPES
|
8
8
|
|
9
9
|
delegate :email, to: :user, allow_nil: true
|
@@ -15,13 +15,8 @@ class Role < AbstractAdapter
|
|
15
15
|
{ ownable_type: { values: OWNABLE_TYPES } }
|
16
16
|
end
|
17
17
|
|
18
|
-
def ownable
|
19
|
-
# return the SuperUser null object
|
20
|
-
ownable_type == 'SuperUser' ? SuperUser.new : super
|
21
|
-
end
|
22
|
-
|
23
18
|
def self.ownable_assign_options(_model=nil)
|
24
|
-
(
|
19
|
+
(Company.all + Project.all).map { |i| [ "#{i.class}: #{i.name}", "#{i.class}-#{i.id}"] }
|
25
20
|
end
|
26
21
|
|
27
22
|
def ownable_assign
|
@@ -2,7 +2,7 @@
|
|
2
2
|
class User < AbstractAdapter
|
3
3
|
# Include default devise modules. Others available are:
|
4
4
|
# :confirmable, :lockable, :timeoutable and :omniauthable
|
5
|
-
devise :database_authenticatable, :registerable, :
|
5
|
+
devise :database_authenticatable, :registerable, :confirmable,
|
6
6
|
:recoverable, :rememberable, :trackable, :validatable, :lockable
|
7
7
|
|
8
8
|
scope :active, -> { where(:locked_at => nil) }
|
@@ -41,7 +41,7 @@ class User < AbstractAdapter
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def superuser?
|
44
|
-
|
44
|
+
superuser
|
45
45
|
end
|
46
46
|
|
47
47
|
def admin?(record)
|
@@ -6,9 +6,8 @@ require "action_controller/railtie"
|
|
6
6
|
require "action_mailer/railtie"
|
7
7
|
require "action_view/railtie"
|
8
8
|
#require "sprockets/railtie"
|
9
|
-
require 'activerecord-tableless'
|
10
9
|
require 'devise'
|
11
|
-
require 'devise/async'
|
10
|
+
#require 'devise/async'
|
12
11
|
require 'grape-swagger'
|
13
12
|
require 'grape-entity'
|
14
13
|
# require "rails/test_unit/railtie"
|
@@ -32,7 +31,7 @@ module Dummy
|
|
32
31
|
# config.i18n.default_locale = :de
|
33
32
|
|
34
33
|
# Do not swallow errors in after_commit/after_rollback callbacks.
|
35
|
-
config.active_record.raise_in_transactional_callbacks = true
|
34
|
+
#config.active_record.raise_in_transactional_callbacks = true
|
36
35
|
|
37
36
|
end
|
38
37
|
end
|
@@ -15,6 +15,7 @@ Rails.application.configure do
|
|
15
15
|
|
16
16
|
# Don't care if the mailer can't send.
|
17
17
|
config.action_mailer.raise_delivery_errors = false
|
18
|
+
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
18
19
|
|
19
20
|
# Print deprecation notices to the Rails logger.
|
20
21
|
config.active_support.deprecation = :log
|
@@ -63,7 +63,7 @@ Rails.application.configure do
|
|
63
63
|
# Ignore bad email addresses and do not raise email delivery errors.
|
64
64
|
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
65
65
|
# config.action_mailer.raise_delivery_errors = false
|
66
|
-
|
66
|
+
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
67
67
|
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
68
68
|
# the I18n.default_locale when a translation cannot be found).
|
69
69
|
config.i18n.fallbacks = true
|
@@ -31,6 +31,7 @@ Dummy::Application.configure do
|
|
31
31
|
# ActionMailer::Base.deliveries array.
|
32
32
|
config.action_mailer.perform_deliveries = false
|
33
33
|
config.action_mailer.delivery_method = :test
|
34
|
+
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
34
35
|
|
35
36
|
# Randomize the order test cases are executed.
|
36
37
|
config.active_support.test_order = :random
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Be sure to restart your server when you modify this file.
|
2
2
|
|
3
3
|
# Version of your assets, change this if you want to expire all your assets.
|
4
|
-
Rails.application.config.assets.version = '1.0'
|
4
|
+
#Rails.application.config.assets.version = '1.0'
|
5
5
|
|
6
6
|
# Add additional assets to the asset load path
|
7
7
|
# Rails.application.config.assets.paths << Emoji.images_path
|
@@ -6,7 +6,7 @@ Devise.setup do |config|
|
|
6
6
|
# confirmation, reset password and unlock tokens in the database.
|
7
7
|
# Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key`
|
8
8
|
# by default. You can change it below and use your own secret key.
|
9
|
-
|
9
|
+
config.secret_key = 'c84d39010264fc71de6cbf2897952c90f92c1b6c7a38cd83c020e84ee343d2aff10b2aa91c24e2911cdb01bf0039cd89e45ff636f73a50dc449a0c814958f6e3'
|
10
10
|
|
11
11
|
# ==> Mailer Configuration
|
12
12
|
# Configure the e-mail address which will be shown in Devise::Mailer,
|
@@ -1,2 +1,2 @@
|
|
1
1
|
#require 'devise/async'
|
2
|
-
Devise::Async.backend = :sidekiq
|
2
|
+
#Devise::Async.backend = :sidekiq
|
@@ -9,6 +9,8 @@ class DeviseCreateUsers < ActiveRecord::Migration
|
|
9
9
|
t.string :reset_password_token
|
10
10
|
t.datetime :reset_password_sent_at
|
11
11
|
|
12
|
+
t.boolean :superuser, default: false
|
13
|
+
|
12
14
|
## Rememberable
|
13
15
|
t.datetime :remember_created_at
|
14
16
|
|
@@ -16,8 +18,8 @@ class DeviseCreateUsers < ActiveRecord::Migration
|
|
16
18
|
t.integer :sign_in_count, default: 0, null: false
|
17
19
|
t.datetime :current_sign_in_at
|
18
20
|
t.datetime :last_sign_in_at
|
19
|
-
t.inet :current_sign_in_ip
|
20
|
-
t.inet :last_sign_in_ip
|
21
|
+
#t.inet :current_sign_in_ip
|
22
|
+
#t.inet :last_sign_in_ip
|
21
23
|
|
22
24
|
## Confirmable
|
23
25
|
# t.string :confirmation_token
|
@@ -22,8 +22,8 @@ class DeviseCreateAdminUsers < ActiveRecord::Migration
|
|
22
22
|
t.integer :sign_in_count, default: 0, null: false
|
23
23
|
t.datetime :current_sign_in_at
|
24
24
|
t.datetime :last_sign_in_at
|
25
|
-
t.inet :current_sign_in_ip
|
26
|
-
t.inet :last_sign_in_ip
|
25
|
+
#t.inet :current_sign_in_ip
|
26
|
+
#t.inet :last_sign_in_ip
|
27
27
|
|
28
28
|
## Confirmable
|
29
29
|
# t.string :confirmation_token
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -261,6 +261,7 @@ ActiveRecord::Schema.define(version: 20150909225019) do
|
|
261
261
|
t.integer "failed_attempts", default: 0, null: false
|
262
262
|
t.string "unlock_token"
|
263
263
|
t.datetime "locked_at"
|
264
|
+
t.boolean "superuser", default: false, null: false
|
264
265
|
t.string "authentication_token"
|
265
266
|
t.string "confirmation_token"
|
266
267
|
t.datetime "confirmed_at"
|
data/spec/models/role_spec.rb
CHANGED
@@ -7,11 +7,6 @@ RSpec.describe Role, type: :model do
|
|
7
7
|
let(:company) { Company.make! }
|
8
8
|
let(:project) { Project.make! }
|
9
9
|
|
10
|
-
it "allows user assignment to super user" do
|
11
|
-
ur = Role.new(user: user, ownable: SuperUser.new )
|
12
|
-
ur.valid?.should be_truthy
|
13
|
-
end
|
14
|
-
|
15
10
|
it "allows user assignment to company admin" do
|
16
11
|
ur = Role.create(user:user, ownable: company)
|
17
12
|
ur.valid?.should be_truthy
|
@@ -25,8 +20,7 @@ RSpec.describe Role, type: :model do
|
|
25
20
|
context "User helper methods" do
|
26
21
|
it "should register a user as a super user" do
|
27
22
|
user.superuser?.should == false
|
28
|
-
|
29
|
-
user.reload
|
23
|
+
user.superuser = true
|
30
24
|
user.superuser?.should == true
|
31
25
|
end
|
32
26
|
|
data/spec/models/user_spec.rb
CHANGED
@@ -113,11 +113,11 @@ RSpec.describe User, type: :model do
|
|
113
113
|
end
|
114
114
|
|
115
115
|
it "should cascade deletes to chat_user, messages, and read logs" do
|
116
|
-
ChatUser.where(discussion.id).size.should == 3
|
117
|
-
ChatMessage.where(discussion.id).size.should == 2
|
116
|
+
ChatUser.where(chat_id: discussion.id).size.should == 3
|
117
|
+
ChatMessage.where(chat_id: discussion.id).size.should == 2
|
118
118
|
discussion.destroy
|
119
|
-
ChatUser.where(discussion.id).size.should == 0
|
120
|
-
ChatMessage.where(discussion.id).size.should == 0
|
119
|
+
ChatUser.where(chat_id: discussion.id).size.should == 0
|
120
|
+
ChatMessage.where(chat_id: discussion.id).size.should == 0
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
@@ -53,8 +53,8 @@ describe Dummy::ProjectAPI, type: :request do
|
|
53
53
|
|
54
54
|
context "via nested attributes" do
|
55
55
|
it "should create a team with users" do
|
56
|
-
p = {
|
57
|
-
team_users_attributes: [{ user_id: @u1.id }, { user_id: @u2.id }]
|
56
|
+
p = {
|
57
|
+
name: 'New Team', team_users_attributes: [{ user_id: @u1.id }, { user_id: @u2.id }]
|
58
58
|
}
|
59
59
|
post "/api/v1/projects/#{project.id}/teams", p
|
60
60
|
response.should be_success
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'rails_helper'
|
2
|
-
|
3
2
|
describe Dummy::RoleAPI, type: :request do
|
4
3
|
let(:role) { Role.last }
|
5
4
|
let(:user) { User.last }
|
5
|
+
let(:company) { Company.last }
|
6
6
|
|
7
7
|
before :all do
|
8
|
+
c = Company.make!
|
8
9
|
Role.destroy_all
|
9
|
-
User.make!
|
10
|
-
Role.make!(user_id: User.last.id, ownable_type:
|
10
|
+
User.make!(superuser: true)
|
11
|
+
Role.make!(user_id: User.last.id, ownable_id: c.id, ownable_type: c.class)
|
11
12
|
end
|
12
13
|
|
13
14
|
it 'should return a list of user roles' do
|
@@ -29,13 +30,13 @@ describe Dummy::RoleAPI, type: :request do
|
|
29
30
|
end
|
30
31
|
|
31
32
|
it 'should not duplicate user roles' do
|
32
|
-
post '/api/v1/roles', { user_id: user.id, ownable_type: '
|
33
|
+
post '/api/v1/roles', { user_id: user.id, ownable_type: 'Company', ownable_id: company.id }
|
33
34
|
response.code.should == '400'
|
34
35
|
json['error'].should =~ /user has already been assigned that role/
|
35
36
|
end
|
36
37
|
|
37
38
|
it 'validates ownable type value specified in grape_validations' do
|
38
|
-
post '/api/v1/roles', { user_id: user.id, ownable_type: '
|
39
|
+
post '/api/v1/roles', { user_id: user.id, ownable_type: 'NotCompany' }
|
39
40
|
response.code.should == '400'
|
40
41
|
json['error'].should eq "ownable_type does not have a valid value"
|
41
42
|
end
|
@@ -98,6 +98,15 @@ describe Dummy::UserAPI, type: :request do
|
|
98
98
|
json['error'].should == "Email: is invalid, Password: can't be blank"
|
99
99
|
end
|
100
100
|
|
101
|
+
it "should return only the records that were created at a nested endpoint" do
|
102
|
+
new_company = Company.make!
|
103
|
+
post "/api/v1/users/#{user.id}/roles", {ownable_type: 'Company', ownable_id: new_company.id}
|
104
|
+
response.should be_success
|
105
|
+
json.size.should eq 1
|
106
|
+
json.first['ownable_id'].should eq new_company.id
|
107
|
+
end
|
108
|
+
|
109
|
+
|
101
110
|
let(:params) do
|
102
111
|
{ email: 'test@test.com', password: 'abc12345', roles_attributes:[] }
|
103
112
|
end
|
@@ -148,8 +157,9 @@ describe Dummy::UserAPI, type: :request do
|
|
148
157
|
put "/api/v1/users/#{user.id}", params
|
149
158
|
|
150
159
|
response.should be_success
|
151
|
-
|
152
|
-
user.
|
160
|
+
json['avatar_url'].should eq Image.last.file.url(:medium)
|
161
|
+
user.avatar.should eq Image.last
|
162
|
+
user.avatar_url.should eq Image.last.file.url(:medium)
|
153
163
|
end
|
154
164
|
|
155
165
|
it "should upload a user avatar via the nested route, to test the restful api's handling of has_one associations" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: introspective_grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Buermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -17,9 +17,6 @@ dependencies:
|
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 3.0.0
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 5.0.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,9 +24,6 @@ dependencies:
|
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 3.0.0
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: 5.0.0
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: grape
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,20 +164,6 @@ dependencies:
|
|
170
164
|
- - ">="
|
171
165
|
- !ruby/object:Gem::Version
|
172
166
|
version: '0'
|
173
|
-
- !ruby/object:Gem::Dependency
|
174
|
-
name: devise-async
|
175
|
-
requirement: !ruby/object:Gem::Requirement
|
176
|
-
requirements:
|
177
|
-
- - ">="
|
178
|
-
- !ruby/object:Gem::Version
|
179
|
-
version: '0'
|
180
|
-
type: :development
|
181
|
-
prerelease: false
|
182
|
-
version_requirements: !ruby/object:Gem::Requirement
|
183
|
-
requirements:
|
184
|
-
- - ">="
|
185
|
-
- !ruby/object:Gem::Version
|
186
|
-
version: '0'
|
187
167
|
- !ruby/object:Gem::Dependency
|
188
168
|
name: paperclip
|
189
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -240,20 +220,6 @@ dependencies:
|
|
240
220
|
- - ">="
|
241
221
|
- !ruby/object:Gem::Version
|
242
222
|
version: '0'
|
243
|
-
- !ruby/object:Gem::Dependency
|
244
|
-
name: activerecord-tableless
|
245
|
-
requirement: !ruby/object:Gem::Requirement
|
246
|
-
requirements:
|
247
|
-
- - "~>"
|
248
|
-
- !ruby/object:Gem::Version
|
249
|
-
version: '1.0'
|
250
|
-
type: :development
|
251
|
-
prerelease: false
|
252
|
-
version_requirements: !ruby/object:Gem::Requirement
|
253
|
-
requirements:
|
254
|
-
- - "~>"
|
255
|
-
- !ruby/object:Gem::Version
|
256
|
-
version: '1.0'
|
257
223
|
description: Introspectively configure deeply nested RESTful Grape APIs for ActiveRecord
|
258
224
|
models.
|
259
225
|
email:
|
@@ -281,11 +247,19 @@ files:
|
|
281
247
|
- app/views/.keep
|
282
248
|
- bin/rails
|
283
249
|
- gemfiles/2.0.0-Gemfile
|
250
|
+
- gemfiles/2.2.0-Gemfile
|
251
|
+
- gemfiles/Gemfile.rails.3.2.22
|
252
|
+
- gemfiles/Gemfile.rails.4.1.13
|
253
|
+
- gemfiles/Gemfile.rails.4.2.7.1
|
254
|
+
- gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
255
|
+
- gemfiles/Gemfile.rails.5.0.1
|
256
|
+
- gemfiles/Gemfile.rails.master
|
284
257
|
- introspective_grape.gemspec
|
285
258
|
- lib/.DS_Store
|
286
259
|
- lib/introspective_grape.rb
|
287
260
|
- lib/introspective_grape/api.rb
|
288
261
|
- lib/introspective_grape/camel_snake.rb
|
262
|
+
- lib/introspective_grape/create_helpers.rb
|
289
263
|
- lib/introspective_grape/doc.rb
|
290
264
|
- lib/introspective_grape/filters.rb
|
291
265
|
- lib/introspective_grape/formatter/camel_json.rb
|
@@ -336,7 +310,6 @@ files:
|
|
336
310
|
- spec/dummy/app/models/project.rb
|
337
311
|
- spec/dummy/app/models/project_job.rb
|
338
312
|
- spec/dummy/app/models/role.rb
|
339
|
-
- spec/dummy/app/models/super_user.rb
|
340
313
|
- spec/dummy/app/models/team.rb
|
341
314
|
- spec/dummy/app/models/team_user.rb
|
342
315
|
- spec/dummy/app/models/user.rb
|
@@ -506,7 +479,6 @@ test_files:
|
|
506
479
|
- spec/dummy/app/models/project.rb
|
507
480
|
- spec/dummy/app/models/project_job.rb
|
508
481
|
- spec/dummy/app/models/role.rb
|
509
|
-
- spec/dummy/app/models/super_user.rb
|
510
482
|
- spec/dummy/app/models/team.rb
|
511
483
|
- spec/dummy/app/models/team_user.rb
|
512
484
|
- spec/dummy/app/models/user.rb
|
@@ -1,11 +0,0 @@
|
|
1
|
-
#require 'activerecord-tableless'
|
2
|
-
class SuperUser < AbstractAdapter
|
3
|
-
# An empty ActiveRecord association for the polymorphic identity on Role.
|
4
|
-
# We could also just create a SuperUser table with one record to do this...
|
5
|
-
has_no_table :database => :pretend_success
|
6
|
-
|
7
|
-
def name
|
8
|
-
'Admin'
|
9
|
-
end
|
10
|
-
|
11
|
-
end
|