snfoil-rails 0.5.4 → 0.8.1
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/README.md +1 -1
- data/lib/generators/sn_foil/all/all_generator.rb +50 -0
- data/lib/generators/sn_foil/context/context_generator.rb +41 -0
- data/lib/generators/sn_foil/context/templates/context.erb +9 -0
- data/lib/generators/sn_foil/controller/controller_generator.rb +52 -0
- data/lib/generators/sn_foil/controller/templates/api_controller.erb +14 -0
- data/lib/generators/sn_foil/controller/templates/controller.erb +14 -0
- data/lib/generators/sn_foil/jsonapi_deserializer/jsonapi_deserializer_generator.rb +41 -0
- data/lib/generators/sn_foil/jsonapi_deserializer/templates/jsonapi_deserializer.erb +12 -0
- data/lib/generators/sn_foil/jsonapi_serializer/jsonapi_serializer_generator.rb +41 -0
- data/lib/generators/sn_foil/jsonapi_serializer/templates/jsonapi_serializer.erb +20 -0
- data/lib/generators/sn_foil/policy/policy_generator.rb +41 -0
- data/lib/generators/sn_foil/policy/templates/policy.erb +22 -0
- data/lib/generators/sn_foil/searcher/searcher_generator.rb +41 -0
- data/lib/generators/sn_foil/searcher/templates/searcher.erb +7 -0
- data/lib/sn_foil/configuration/lazy_jsonapi_serializer.rb +87 -0
- data/lib/sn_foil/controller/api.rb +3 -3
- data/lib/sn_foil/jsonapi_deserializer.rb +11 -5
- data/lib/sn_foil/rails.rb +2 -0
- data/lib/sn_foil/rails/engine.rb +2 -0
- data/lib/sn_foil/rails/version.rb +1 -1
- data/lib/sn_foil/searcher.rb +3 -3
- metadata +32 -18
- data/lib/generators/sn_foil/sn_foil_generator.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3d00195925208a499c8ddc53cd7237ad12bf835fb2f8919e8a367d6c42ea0e51
|
4
|
+
data.tar.gz: 8589deefc725c97dd946126aba442ff0b5f0f1a20b769245ddc3c43c9b0c14df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d32a067a6eba8e506678483b3249df6b0297667edac1fe5764dac986978212d4840456d97cf44e3cefff0d6b5388bfbce88819a226b1980f0fad67532cadd004
|
7
|
+
data.tar.gz: 529206939a96babfc648c6cc88528272e8035a21283d033cc9a90565b4dde9e198dddcbcc051615ebe826afbf55c554ba396687c9250cca589ea9bc9733dee0d
|
data/README.md
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
class AllGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :model, type: :string
|
8
|
+
|
9
|
+
class_option(:type, desc: 'Generate Base or API', type: :string, default: 'base')
|
10
|
+
class_option(:skip_model, desc: 'Skip Model Creation', type: :boolean, default: false)
|
11
|
+
|
12
|
+
def add_model
|
13
|
+
rails_command "generate model #{call_args.join(' ')}", call_options
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_policy
|
17
|
+
rails_command "generate sn_foil:policy #{call_args.join(' ')}", call_options
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_searcher
|
21
|
+
rails_command "generate sn_foil:searcher #{call_args.join(' ')}", call_options
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_context
|
25
|
+
rails_command "generate sn_foil:context #{call_args.join(' ')}", call_options
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_jsonapi_serializer
|
29
|
+
rails_command "generate sn_foil:jsonapi_serializer #{call_args.join(' ')}", call_options
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_jsonapi_deserializer
|
33
|
+
rails_command "generate sn_foil:jsonapi_deserializer #{call_args.join(' ')}", call_options
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_controller
|
37
|
+
rails_command "generate sn_foil:controller #{call_args.join(' ')}", call_options
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def call_args
|
43
|
+
@call_args ||= [model].concat(args)
|
44
|
+
end
|
45
|
+
|
46
|
+
def call_options
|
47
|
+
@call_options ||= options.deep_symbolize_keys
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
class ContextGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :model, type: :string
|
8
|
+
|
9
|
+
class_option :path, desc: 'Base path for file', type: :string, default: 'app/contexts'
|
10
|
+
|
11
|
+
def add_app_file
|
12
|
+
file_name = if modules.length.zero?
|
13
|
+
name
|
14
|
+
else
|
15
|
+
"#{modules.join('/')}/#{name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
template('context.erb', "#{options[:path]}/#{file_name}_context.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def name
|
24
|
+
@name ||= model.split('/').last.underscore.singularize
|
25
|
+
end
|
26
|
+
|
27
|
+
def class_name
|
28
|
+
@class_name ||= name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
def modules
|
32
|
+
@modules ||= model.split('/')[0..-2].map(&:underscore)
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_modules
|
36
|
+
return if modules.length.zero?
|
37
|
+
|
38
|
+
@class_modules ||= "#{modules.map(&:camelize).join('::')}::"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
class ControllerGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :model, type: :string
|
8
|
+
|
9
|
+
class_option :type, desc: 'Generate Base or API', type: :string, default: 'base'
|
10
|
+
class_option :path, desc: 'Base path for file', type: :string, default: 'app/controllers'
|
11
|
+
|
12
|
+
def add_app_file
|
13
|
+
template(template_name, "#{options[:path]}/#{file_name}_controller.rb")
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def file_name
|
19
|
+
@file_name ||= if modules.length.zero?
|
20
|
+
name
|
21
|
+
else
|
22
|
+
"#{modules.join('/')}/#{name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def template_name
|
27
|
+
@template_name ||= if options[:type] == 'api'
|
28
|
+
'api_controller.erb'
|
29
|
+
else
|
30
|
+
'controller.erb'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def name
|
35
|
+
@name ||= model.split('/').last.underscore.pluralize
|
36
|
+
end
|
37
|
+
|
38
|
+
def class_name
|
39
|
+
@class_name ||= name.camelize
|
40
|
+
end
|
41
|
+
|
42
|
+
def modules
|
43
|
+
@modules ||= model.split('/')[0..-2].map(&:underscore)
|
44
|
+
end
|
45
|
+
|
46
|
+
def class_modules
|
47
|
+
return if modules.length.zero?
|
48
|
+
|
49
|
+
@class_modules ||= "#{modules.map(&:camelize).join('::')}::"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class <%= class_modules %><%= class_name %>Controller < SnFoil::Controller::API
|
4
|
+
context <%= class_name.singularize %>Context
|
5
|
+
serializer <%= class_name.singularize %>JsonapiSerializer
|
6
|
+
deserializer <%= class_name.singularize %>JsonapiDeserializer
|
7
|
+
|
8
|
+
# SnFoil::Controller requires current_entity or current_user defined to properly scope
|
9
|
+
# all queries, otherwise data leaks could occur
|
10
|
+
#
|
11
|
+
# def current_entity
|
12
|
+
# # logic to find authenticated user
|
13
|
+
# end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class <%= class_modules %><%= class_name %>Controller < SnFoil::Controller::Base
|
4
|
+
context <%= name.singularize.camelcase %>Context
|
5
|
+
serializer <%= name.singularize.camelcase %>JsonapiSerializer
|
6
|
+
deserializer <%= name.singularize.camelcase %>JsonapiDeserializer
|
7
|
+
|
8
|
+
# SnFoil::Controller requires current_entity or current_user defined to properly scope
|
9
|
+
# all queries, otherwise data leaks could occur
|
10
|
+
#
|
11
|
+
# def current_entity
|
12
|
+
# # logic to find authenticated user
|
13
|
+
# end
|
14
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
class JsonapiDeserializerGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :model, type: :string
|
8
|
+
|
9
|
+
class_option :path, desc: 'Base path for file', type: :string, default: 'app/jsonapi_deserializers'
|
10
|
+
|
11
|
+
def add_app_file
|
12
|
+
file_name = if modules.length.zero?
|
13
|
+
name
|
14
|
+
else
|
15
|
+
"#{modules.join('/')}/#{name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
template('jsonapi_deserializer.erb', "#{options[:path]}/#{file_name}_jsonapi_deserializer.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def name
|
24
|
+
@name ||= model.split('/').last.underscore.singularize
|
25
|
+
end
|
26
|
+
|
27
|
+
def class_name
|
28
|
+
@class_name ||= name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
def modules
|
32
|
+
@modules ||= model.split('/')[0..-2].map(&:underscore)
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_modules
|
36
|
+
return if modules.length.zero?
|
37
|
+
|
38
|
+
@class_modules ||= "#{modules.map(&:camelize).join('::')}::"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class <%= class_modules %><%= class_name %>JsonapiDeserializer
|
4
|
+
include SnFoil::JsonapiDeserializer
|
5
|
+
|
6
|
+
# Add attributes of the model you want to serializer with the following syntax
|
7
|
+
attributes :id
|
8
|
+
|
9
|
+
# Add relationships with the following syntax
|
10
|
+
# belongs_to :store, serializer: Jsonapi::StoreJsonapiSerializer
|
11
|
+
# has_many :locations, serializer: Jsonapi::LocationJsonapiSerializer
|
12
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
class JsonapiSerializerGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :model, type: :string
|
8
|
+
|
9
|
+
class_option :path, desc: 'Base path for file', type: :string, default: 'app/jsonapi_serializers'
|
10
|
+
|
11
|
+
def add_app_file
|
12
|
+
file_name = if modules.length.zero?
|
13
|
+
name
|
14
|
+
else
|
15
|
+
"#{modules.join('/')}/#{name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
template('jsonapi_serializer.erb', "#{options[:path]}/#{file_name}_jsonapi_serializer.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def name
|
24
|
+
@name ||= model.split('/').last.underscore.singularize
|
25
|
+
end
|
26
|
+
|
27
|
+
def class_name
|
28
|
+
@class_name ||= name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
def modules
|
32
|
+
@modules ||= model.split('/')[0..-2].map(&:underscore)
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_modules
|
36
|
+
return if modules.length.zero?
|
37
|
+
|
38
|
+
@class_modules ||= "#{modules.map(&:camelize).join('::')}::"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class <%= class_modules %><%= class_name %>JsonapiSerializer
|
4
|
+
include SnFoil::JsonapiSerializer
|
5
|
+
|
6
|
+
set_id :id
|
7
|
+
set_type :<%= name.pluralize.dasherize %>
|
8
|
+
|
9
|
+
# SnFoil::JsonapiSerializer is just a wrapper for jsonapi-serializer (https://github.com/jsonapi-serializer/jsonapi-serializer)
|
10
|
+
# with some defaults added in
|
11
|
+
|
12
|
+
# Add attributes of the model you want to serializer with the following syntax
|
13
|
+
# attributes :name
|
14
|
+
# :description
|
15
|
+
# :logo_url
|
16
|
+
|
17
|
+
# Add relationships with the following syntax
|
18
|
+
# belongs_to :store, serializer: Jsonapi::StoreJsonapiSerializer
|
19
|
+
# has_many :locations, serializer: Jsonapi::LocationJsonapiSerializer
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
class PolicyGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :model, type: :string
|
8
|
+
|
9
|
+
class_option :path, desc: 'Base path for file', type: :string, default: 'app/policies'
|
10
|
+
|
11
|
+
def add_app_file
|
12
|
+
file_name = if modules.length.zero?
|
13
|
+
name
|
14
|
+
else
|
15
|
+
"#{modules.join('/')}/#{name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
template('policy.erb', "#{options[:path]}/#{file_name}_policy.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def name
|
24
|
+
@name ||= model.split('/').last.underscore.singularize
|
25
|
+
end
|
26
|
+
|
27
|
+
def class_name
|
28
|
+
@class_name ||= name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
def modules
|
32
|
+
@modules ||= model.split('/')[0..-2].map(&:underscore)
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_modules
|
36
|
+
return if modules.length.zero?
|
37
|
+
|
38
|
+
@class_modules ||= "#{modules.map(&:camelize).join('::')}::"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class <%= class_modules %><%= class_name %>Policy
|
4
|
+
include SnFoil::Policy
|
5
|
+
# A SnFoil::Policy is just a Pundit policy (https://github.com/varvet/pundit)
|
6
|
+
# with some defaults
|
7
|
+
# Available methods: show?, create?, update?, destroy?, index?, associate?
|
8
|
+
|
9
|
+
# def show?
|
10
|
+
# true
|
11
|
+
# end
|
12
|
+
|
13
|
+
# class Scope
|
14
|
+
# # available read-only attributes
|
15
|
+
# # - scope: the default scope passed into the policy (ex: an ActiveRecord::Relation)
|
16
|
+
# # - entity: the object that the scope is build around (ex: a User)
|
17
|
+
|
18
|
+
# def resolve
|
19
|
+
# # the new default scope
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
class SearcherGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates', __dir__)
|
6
|
+
|
7
|
+
argument :model, type: :string
|
8
|
+
|
9
|
+
class_option :path, desc: 'Base path for file', type: :string, default: 'app/searchers'
|
10
|
+
|
11
|
+
def add_app_file
|
12
|
+
file_name = if modules.length.zero?
|
13
|
+
name
|
14
|
+
else
|
15
|
+
"#{modules.join('/')}/#{name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
template('searcher.erb', "#{options[:path]}/#{file_name}_searcher.rb")
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def name
|
24
|
+
@name ||= model.split('/').last.underscore.pluralize
|
25
|
+
end
|
26
|
+
|
27
|
+
def class_name
|
28
|
+
@class_name ||= name.camelize
|
29
|
+
end
|
30
|
+
|
31
|
+
def modules
|
32
|
+
@modules ||= model.split('/')[0..-2].map(&:underscore)
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_modules
|
36
|
+
return if modules.length.zero?
|
37
|
+
|
38
|
+
@class_modules ||= "#{modules.map(&:camelize).join('::')}::"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnFoil
|
4
|
+
module Configuration
|
5
|
+
module LazyJsonapiSerializer
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def belongs_to(relationship_name, options = {}, &block)
|
10
|
+
block = belongs_to_optimized_block(relationship_name, options, &block)
|
11
|
+
super(relationship_name, options, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_one(relationship_name, options = {}, &block) # rubocop:disable Naming/PredicateName reason: method override
|
15
|
+
super(relationship_name, has_relation_optimized_options(relationship_name, options), &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_many(relationship_name, options = {}, &block) # rubocop:disable Naming/PredicateName reason: method override
|
19
|
+
super(relationship_name, has_relation_optimized_options(relationship_name, options), &block)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# We need to parse the include block because FastJsonAPI does not allow access to the pre-parsed includes
|
25
|
+
def parse_include(params)
|
26
|
+
return [] unless params[:include]
|
27
|
+
|
28
|
+
if params[:include].is_a?(String)
|
29
|
+
params[:include].split(',')
|
30
|
+
else
|
31
|
+
params[:include]
|
32
|
+
end.map { |r| r.to_s.dasherize }.join(',')
|
33
|
+
end
|
34
|
+
|
35
|
+
def lookup_full_object_for_belongs_to(record, relationship_name, options, params)
|
36
|
+
return unless parse_include(params).include?(relationship_name.to_s.dasherize)
|
37
|
+
|
38
|
+
record.send(options[:object_method_name] || relationship_name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_substitute_object_for_belongs_to(record, relationship_name, options)
|
42
|
+
relationship_id = options[:id_method_name] || "#{relationship_name}_id".to_sym
|
43
|
+
OpenStruct.new(id: record.send(relationship_id))
|
44
|
+
end
|
45
|
+
|
46
|
+
def belongs_to_optimized_block(relationship_name, options = {}, &block)
|
47
|
+
return block if options[:skip_optimization] == true || block
|
48
|
+
|
49
|
+
proc do |record, params|
|
50
|
+
if params && params[:include]
|
51
|
+
lookup_full_object(record_for_belongs_to, relationship_name, options, params)
|
52
|
+
else
|
53
|
+
create_substitute_object_for_belongs_to(record, relationship_name, options)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_included_proc_for_has_relation(relationship_name)
|
59
|
+
proc do |_record, params|
|
60
|
+
if params && params[:include]
|
61
|
+
parse_include(params).include?(relationship_name.to_s.dasherize)
|
62
|
+
else
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def create_if_proc_for_has_relation(if_proc, included_proc)
|
69
|
+
if if_proc.present?
|
70
|
+
proc do |record, params|
|
71
|
+
FastJsonapi.call_proc(included_proc, record, params) && FastJsonapi.call_proc(if_proc, record, params)
|
72
|
+
end
|
73
|
+
else
|
74
|
+
included_proc
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def has_relation_optimized_options(relationship_name, options) # rubocop:disable Naming/PredicateName reason: method override
|
79
|
+
return options if options[:skip_optimization] == true
|
80
|
+
|
81
|
+
options[:if] = create_if_proc_for_has_relation(options[:if], create_included_proc_for_has_relation(relationship_name))
|
82
|
+
options
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -44,7 +44,7 @@ module SnFoil
|
|
44
44
|
render json: serializer(**options).new(model,
|
45
45
|
**options,
|
46
46
|
params: (options[:controller_params] || options[:params] || {})
|
47
|
-
.merge(current_entity:
|
47
|
+
.merge(current_entity: context_entity)).serializable_hash
|
48
48
|
else
|
49
49
|
render json: model.errors, status: :unprocessable_entity
|
50
50
|
end
|
@@ -62,7 +62,7 @@ module SnFoil
|
|
62
62
|
render json: serializer(**options).new(paginate(results, **options),
|
63
63
|
**options,
|
64
64
|
params: (options[:controller_params] || options[:params] || {})
|
65
|
-
.merge(current_entity:
|
65
|
+
.merge(current_entity: context_entity),
|
66
66
|
meta: meta(results, **options))
|
67
67
|
.serializable_hash
|
68
68
|
end
|
@@ -71,7 +71,7 @@ module SnFoil
|
|
71
71
|
render json: serializer(**options).new(model,
|
72
72
|
**options,
|
73
73
|
params: (options[:controller_params] || options[:params] || {})
|
74
|
-
.merge(current_entity:
|
74
|
+
.merge(current_entity: context_entity)).serializable_hash
|
75
75
|
end
|
76
76
|
|
77
77
|
private
|
@@ -32,6 +32,7 @@ module SnFoil
|
|
32
32
|
end
|
33
33
|
|
34
34
|
attr_reader :object, :included, :options
|
35
|
+
|
35
36
|
def initialize(object, included: nil, **options)
|
36
37
|
@object = object
|
37
38
|
@included = included || object[:included]
|
@@ -88,11 +89,12 @@ module SnFoil
|
|
88
89
|
end
|
89
90
|
|
90
91
|
def apply_attribute_transform(attributes, data, key, transform_type:, **opts)
|
91
|
-
|
92
|
+
case transform_type
|
93
|
+
when :attribute
|
92
94
|
parse_attribute_transform(attributes, data, key, **opts)
|
93
|
-
|
95
|
+
when :has_one
|
94
96
|
parse_has_one_relationship(attributes, data, key, **opts)
|
95
|
-
|
97
|
+
when :has_many
|
96
98
|
parse_has_many_relationship(attributes, data, key, **opts)
|
97
99
|
end
|
98
100
|
end
|
@@ -100,7 +102,7 @@ module SnFoil
|
|
100
102
|
def parse_attribute_transform(attributes, data, key, **opts)
|
101
103
|
return attributes unless data.dig(:attributes, key)
|
102
104
|
|
103
|
-
attributes.merge(
|
105
|
+
attributes.merge({ opts.fetch(:key) { key } => data[:attributes][key] })
|
104
106
|
end
|
105
107
|
|
106
108
|
def parse_relationships(attributes, data)
|
@@ -138,7 +140,7 @@ module SnFoil
|
|
138
140
|
end
|
139
141
|
|
140
142
|
def lookup_relationship(type:, id: nil, lid: nil, **_opts)
|
141
|
-
|
143
|
+
check_for_id(id, lid)
|
142
144
|
|
143
145
|
included&.find do |x|
|
144
146
|
x[:type].eql?(type) &&
|
@@ -149,5 +151,9 @@ module SnFoil
|
|
149
151
|
end
|
150
152
|
end
|
151
153
|
end
|
154
|
+
|
155
|
+
def check_for_id(id, lid)
|
156
|
+
raise ::ArgumentError, "missing keyword: id or lid for type: #{type}" unless id || lid
|
157
|
+
end
|
152
158
|
end
|
153
159
|
end
|
data/lib/sn_foil/rails.rb
CHANGED
data/lib/sn_foil/rails/engine.rb
CHANGED
data/lib/sn_foil/searcher.rb
CHANGED
@@ -18,8 +18,8 @@ module SnFoil
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
ASC
|
22
|
-
DESC
|
21
|
+
ASC = 'ASC'
|
22
|
+
DESC = 'DESC'
|
23
23
|
end
|
24
24
|
|
25
25
|
class_methods do
|
@@ -35,7 +35,7 @@ module SnFoil
|
|
35
35
|
@i_order_by_direction = direction
|
36
36
|
end
|
37
37
|
|
38
|
-
def distinct(bool = true)
|
38
|
+
def distinct(bool = true) # rubocop:disable Style/OptionalBooleanParameter reason: class configuration looks better this way
|
39
39
|
@i_is_distinct = bool
|
40
40
|
end
|
41
41
|
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snfoil-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Howes
|
8
8
|
- Danny Murphy
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-06-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -45,14 +45,14 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: '0.
|
48
|
+
version: '0.8'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: '0.
|
55
|
+
version: '0.8'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: bundler
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,42 +129,42 @@ dependencies:
|
|
129
129
|
requirements:
|
130
130
|
- - "~>"
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
132
|
+
version: '1.14'
|
133
133
|
type: :development
|
134
134
|
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
137
|
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version:
|
139
|
+
version: '1.14'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: rubocop-rails
|
142
142
|
requirement: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
144
|
- - "~>"
|
145
145
|
- !ruby/object:Gem::Version
|
146
|
-
version: '2.
|
146
|
+
version: '2.10'
|
147
147
|
type: :development
|
148
148
|
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
151
|
- - "~>"
|
152
152
|
- !ruby/object:Gem::Version
|
153
|
-
version: '2.
|
153
|
+
version: '2.10'
|
154
154
|
- !ruby/object:Gem::Dependency
|
155
155
|
name: rubocop-rspec
|
156
156
|
requirement: !ruby/object:Gem::Requirement
|
157
157
|
requirements:
|
158
158
|
- - "~>"
|
159
159
|
- !ruby/object:Gem::Version
|
160
|
-
version:
|
160
|
+
version: '2.3'
|
161
161
|
type: :development
|
162
162
|
prerelease: false
|
163
163
|
version_requirements: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
165
|
- - "~>"
|
166
166
|
- !ruby/object:Gem::Version
|
167
|
-
version:
|
167
|
+
version: '2.3'
|
168
168
|
- !ruby/object:Gem::Dependency
|
169
169
|
name: sqlite3
|
170
170
|
requirement: !ruby/object:Gem::Requirement
|
@@ -179,7 +179,7 @@ dependencies:
|
|
179
179
|
- - ">="
|
180
180
|
- !ruby/object:Gem::Version
|
181
181
|
version: '0'
|
182
|
-
description:
|
182
|
+
description:
|
183
183
|
email:
|
184
184
|
- howeszy@gmail.com
|
185
185
|
- dmurph24@gmail.com
|
@@ -191,7 +191,21 @@ files:
|
|
191
191
|
- MIT-LICENSE
|
192
192
|
- README.md
|
193
193
|
- Rakefile
|
194
|
-
- lib/generators/sn_foil/
|
194
|
+
- lib/generators/sn_foil/all/all_generator.rb
|
195
|
+
- lib/generators/sn_foil/context/context_generator.rb
|
196
|
+
- lib/generators/sn_foil/context/templates/context.erb
|
197
|
+
- lib/generators/sn_foil/controller/controller_generator.rb
|
198
|
+
- lib/generators/sn_foil/controller/templates/api_controller.erb
|
199
|
+
- lib/generators/sn_foil/controller/templates/controller.erb
|
200
|
+
- lib/generators/sn_foil/jsonapi_deserializer/jsonapi_deserializer_generator.rb
|
201
|
+
- lib/generators/sn_foil/jsonapi_deserializer/templates/jsonapi_deserializer.erb
|
202
|
+
- lib/generators/sn_foil/jsonapi_serializer/jsonapi_serializer_generator.rb
|
203
|
+
- lib/generators/sn_foil/jsonapi_serializer/templates/jsonapi_serializer.erb
|
204
|
+
- lib/generators/sn_foil/policy/policy_generator.rb
|
205
|
+
- lib/generators/sn_foil/policy/templates/policy.erb
|
206
|
+
- lib/generators/sn_foil/searcher/searcher_generator.rb
|
207
|
+
- lib/generators/sn_foil/searcher/templates/searcher.erb
|
208
|
+
- lib/sn_foil/configuration/lazy_jsonapi_serializer.rb
|
195
209
|
- lib/sn_foil/controller/api.rb
|
196
210
|
- lib/sn_foil/controller/base.rb
|
197
211
|
- lib/sn_foil/controller/concerns/change_controller_concern.rb
|
@@ -208,11 +222,11 @@ files:
|
|
208
222
|
- lib/sn_foil/rails/version.rb
|
209
223
|
- lib/sn_foil/searcher.rb
|
210
224
|
- lib/snfoil-rails.rb
|
211
|
-
homepage: https://github.com/
|
225
|
+
homepage: https://github.com/limited-effort/snfoil-rails
|
212
226
|
licenses:
|
213
227
|
- MIT
|
214
228
|
metadata: {}
|
215
|
-
post_install_message:
|
229
|
+
post_install_message:
|
216
230
|
rdoc_options: []
|
217
231
|
require_paths:
|
218
232
|
- lib
|
@@ -220,15 +234,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
220
234
|
requirements:
|
221
235
|
- - ">="
|
222
236
|
- !ruby/object:Gem::Version
|
223
|
-
version:
|
237
|
+
version: 2.5.0
|
224
238
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
225
239
|
requirements:
|
226
240
|
- - ">="
|
227
241
|
- !ruby/object:Gem::Version
|
228
242
|
version: '0'
|
229
243
|
requirements: []
|
230
|
-
rubygems_version: 3.
|
231
|
-
signing_key:
|
244
|
+
rubygems_version: 3.1.4
|
245
|
+
signing_key:
|
232
246
|
specification_version: 4
|
233
247
|
summary: Additional functionality gem for using SnFoil with Rails
|
234
248
|
test_files: []
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class SnFoilGenerator < Rails::Generators::Base
|
4
|
-
source_root File.expand_path('templates', __dir__)
|
5
|
-
argument :model, type: :string
|
6
|
-
|
7
|
-
def generate_sn_foil
|
8
|
-
generate_model
|
9
|
-
generate_controller
|
10
|
-
generate_searcher
|
11
|
-
generate_serializer
|
12
|
-
generate_deserializer
|
13
|
-
generate_policy
|
14
|
-
generate_context
|
15
|
-
Rails.logger.info 'In order to expose your model, it must be added to the config/routes.rb file'
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def generate_context
|
21
|
-
template 'context.erb', "app/contexts/#{model.singularize.underscore}_context.rb"
|
22
|
-
end
|
23
|
-
|
24
|
-
def generate_controller
|
25
|
-
template 'controller.erb', "app/controllers/#{model.pluralize.underscore}_controller.rb"
|
26
|
-
end
|
27
|
-
|
28
|
-
def generate_deserializer
|
29
|
-
template 'jsonapi_deserializer.erb', "app/deserializers/#{model.singularize.underscore}_deserializer.rb"
|
30
|
-
end
|
31
|
-
|
32
|
-
def generate_serializer
|
33
|
-
template 'jsonapi_serializer.erb', "app/serializers/#{model.singularize.underscore}_jsonapi_serializer.rb"
|
34
|
-
end
|
35
|
-
|
36
|
-
def generate_model
|
37
|
-
generate('model', model.underscore) unless File.file? "app/models/#{model.singularize.underscore}.rb"
|
38
|
-
end
|
39
|
-
|
40
|
-
def generate_searcher
|
41
|
-
template 'searcher.erb', "app/searchers/#{model.pluralize.underscore}_searcher.rb"
|
42
|
-
end
|
43
|
-
|
44
|
-
def generate_policy
|
45
|
-
template 'policy.erb', "app/policies/#{model.singularize.underscore}_policy.rb"
|
46
|
-
end
|
47
|
-
end
|