render_json_rails 0.1.4 → 0.2
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/.rubocop.yml +4119 -0
- data/Gemfile +1 -1
- data/README.md +94 -23
- data/Rakefile +3 -1
- data/lib/render_json_rails/concern.rb +50 -33
- data/lib/render_json_rails/helper.rb +2 -2
- data/lib/render_json_rails/version.rb +1 -1
- data/render_json_rails.gemspec +4 -2
- metadata +34 -5
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,51 +1,122 @@
|
|
|
1
1
|
# RenderJsonRails
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
RenderJsonRails pozwala w łatwy sposób dodać możliwość renderowania JSON z ActiveRecord-ów z zależnościami (has_many itp).
|
|
4
|
+
Dzięki temu łatwo jest stworzyć backend Json API np. do pracy z Reactem lub Vue.js
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
## Przykład
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
```ruby
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
class Team < ActiveRecord::Base
|
|
11
|
+
has_many :users
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
include RenderJsonRails::Concern
|
|
14
|
+
|
|
15
|
+
render_json_config name: :team,
|
|
16
|
+
includes: {
|
|
17
|
+
users: User
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class User < ActiveRecord::Base
|
|
22
|
+
belongs_to :team
|
|
23
|
+
|
|
24
|
+
include RenderJsonRails::Concern
|
|
13
25
|
|
|
14
|
-
|
|
26
|
+
render_json_config name: :user,
|
|
27
|
+
except: [:account_id, :id],
|
|
28
|
+
# only: [:login, :email], # jesli wolelibyśmy wymienić pola zamiast je wykluczać przy pomocy "except"
|
|
29
|
+
default_fields: [:login, :email, :calculated_age],
|
|
30
|
+
allowed_methods: [:calculated_age],
|
|
31
|
+
includes: {
|
|
32
|
+
team: Team
|
|
33
|
+
}
|
|
15
34
|
|
|
16
|
-
|
|
17
|
-
|
|
35
|
+
def calculated_age
|
|
36
|
+
rand(100)
|
|
37
|
+
end
|
|
18
38
|
end
|
|
19
39
|
```
|
|
20
40
|
|
|
21
|
-
|
|
41
|
+
Dodajemy też w kontrolerze ```teams_controller.rb```
|
|
22
42
|
|
|
23
|
-
|
|
43
|
+
```ruby
|
|
44
|
+
include RenderJsonRails::Helper
|
|
45
|
+
|
|
46
|
+
def index
|
|
47
|
+
@team = Team.all
|
|
48
|
+
respond_to do |format|
|
|
49
|
+
format.html
|
|
50
|
+
format.json { render_json @team }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
```
|
|
24
54
|
|
|
25
|
-
|
|
55
|
+
i możemy już otrzymać JSON team-u wraz z userami
|
|
26
56
|
|
|
27
|
-
|
|
57
|
+
```html
|
|
58
|
+
http://example.test/teams/1.json?include=users
|
|
59
|
+
```
|
|
28
60
|
|
|
29
|
-
|
|
61
|
+
możemy też określić jakie pola mają być w json
|
|
30
62
|
|
|
31
|
-
|
|
63
|
+
```html
|
|
64
|
+
http://example.test/teams/1.json?fields[team]=name,description
|
|
65
|
+
```
|
|
32
66
|
|
|
33
|
-
|
|
67
|
+
i możemy łączyć to z include
|
|
34
68
|
|
|
35
|
-
|
|
69
|
+
```html
|
|
70
|
+
http://example.text/teams/1.json?fields[team]=name,description&fields[user]=email,name&include=users
|
|
71
|
+
```
|
|
36
72
|
|
|
37
|
-
|
|
73
|
+
include mogą być zagnieżdżane (po kropce)
|
|
38
74
|
|
|
39
|
-
|
|
75
|
+
```html
|
|
76
|
+
http://example.text/teams/1.json?fields[team]=name,description&fields[user]=email,name&fields[role]=name&include=users,users.roles
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Więcej przykładów jest w testach: [test/render_json_rails_test.rb](test/render_json_rails_test.rb)
|
|
40
80
|
|
|
41
|
-
|
|
81
|
+
## Pełny opis ```render_json_config```
|
|
42
82
|
|
|
83
|
+
```ruby
|
|
84
|
+
render_json_config name: :team,
|
|
85
|
+
except: [:account_id, :config], # tych pól nie będzie w json-ie
|
|
86
|
+
only: [:id, :name], # dozwolone pola będą w jsonie (wymiennie z except)
|
|
87
|
+
methods: [:image], # dozwolone i domyślnie wyświetlone metody, ten parametr warto uzywac tylko, gdy nie ma parametru "default_fields" - przy ustawionym "default_fields" trzeba metody wymienic w allowed_methods
|
|
88
|
+
default_fields: [:id, :name, :members], # domyślnie wyświetlone pola + metody
|
|
89
|
+
allowed_methods: [:members], # dozwolone metody, mogą być dodane przez parametr fileds np: fields[team]=id,members
|
|
90
|
+
includes: { # to mozna dołączać za pomoca parametru include np include=users,category
|
|
91
|
+
users: Users,
|
|
92
|
+
category: Category
|
|
93
|
+
}
|
|
94
|
+
```
|
|
43
95
|
|
|
44
|
-
|
|
96
|
+
## Installation
|
|
97
|
+
|
|
98
|
+
Add this line to your application's Gemfile:
|
|
45
99
|
|
|
100
|
+
```ruby
|
|
101
|
+
gem 'render_json_rails'
|
|
46
102
|
```
|
|
47
|
-
gem build render_json_rails.gemspec
|
|
48
103
|
|
|
49
|
-
|
|
104
|
+
And then execute:
|
|
105
|
+
|
|
106
|
+
$ bundle install
|
|
107
|
+
|
|
108
|
+
Or install it yourself as:
|
|
109
|
+
|
|
110
|
+
$ gem install render_json_rails
|
|
111
|
+
|
|
112
|
+
## Tests
|
|
113
|
+
|
|
50
114
|
```
|
|
115
|
+
rake test
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
|
|
121
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/intum/render_json_rails.
|
|
51
122
|
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
require "rake/testtask"
|
|
3
|
+
# require 'active_support/core_ext/object/blank'
|
|
4
|
+
# require 'active_support'
|
|
3
5
|
|
|
4
6
|
Rake::TestTask.new(:test) do |t|
|
|
5
7
|
t.libs << "test"
|
|
@@ -7,4 +9,4 @@ Rake::TestTask.new(:test) do |t|
|
|
|
7
9
|
t.test_files = FileList["test/**/*_test.rb"]
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
task :
|
|
12
|
+
task default: :test
|
|
@@ -17,20 +17,29 @@ module RenderJsonRails
|
|
|
17
17
|
# zostaną one wyświelone w json-ie
|
|
18
18
|
# TODO:
|
|
19
19
|
# [ ] spradzanie czy parametry "fields" i "include" sa ok i jesli nie to error
|
|
20
|
-
def default_json_options(name:, fields: nil, except: nil, methods: nil, allowed_methods: nil)
|
|
20
|
+
def default_json_options(name:, fields: nil, only: nil, except: nil, methods: nil, allowed_methods: nil)
|
|
21
21
|
# name ||= self.name.underscore.gsub('/', '_')
|
|
22
22
|
# raise self.name.underscore.gsub('/', '_')
|
|
23
|
-
except ||= [:account_id, :agent, :ip]
|
|
23
|
+
# except ||= [:account_id, :agent, :ip]
|
|
24
24
|
|
|
25
25
|
options = {}
|
|
26
26
|
if fields && fields[name].present?
|
|
27
|
-
options[:only] = fields[name].split(',').find_all{ |el| !except
|
|
28
|
-
|
|
27
|
+
options[:only] = fields[name].split(',').map{ |e| e.to_s.strip.to_sym }.find_all { |el| !except&.include?(el) }
|
|
28
|
+
if only.present?
|
|
29
|
+
options[:only] = options[:only].find_all do |el|
|
|
30
|
+
only.include?(el) || allowed_methods&.include?(el) || methods&.include?(el)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
options[:methods] = methods&.find_all { |el| options[:only].include?(el) }
|
|
29
34
|
if allowed_methods
|
|
30
|
-
options[:methods] = (options[:methods] || []) | allowed_methods.find_all{ |el| options[:only].include?(el
|
|
35
|
+
options[:methods] = (options[:methods] || []) | allowed_methods.find_all { |el| options[:only].include?(el) }
|
|
36
|
+
end
|
|
37
|
+
if options[:methods].present? && options[:only].present?
|
|
38
|
+
options[:methods].each { |method| options[:only].delete(method) }
|
|
31
39
|
end
|
|
32
40
|
else
|
|
33
41
|
options[:except] = except
|
|
42
|
+
options[:only] = only if only.present?
|
|
34
43
|
options[:methods] = methods
|
|
35
44
|
end
|
|
36
45
|
options
|
|
@@ -38,16 +47,22 @@ module RenderJsonRails
|
|
|
38
47
|
|
|
39
48
|
def render_json_config(config)
|
|
40
49
|
@render_json_config = config
|
|
41
|
-
# @render_json_config[:methods] = [:image]
|
|
42
50
|
end
|
|
43
51
|
|
|
44
|
-
# rubocop:disable Lint/UnusedMethodArgument
|
|
45
52
|
def render_json_options(includes: nil, fields: nil, additional_config: nil)
|
|
46
53
|
raise "należy skonfigurowac render_json metodą: render_json_config" if !defined?(@render_json_config)
|
|
47
54
|
|
|
55
|
+
name = @render_json_config[:name].to_s
|
|
56
|
+
|
|
57
|
+
if (fields.blank? || fields[name].blank?) && @render_json_config[:default_fields].present?
|
|
58
|
+
fields ||= {}
|
|
59
|
+
fields[name] = @render_json_config[:default_fields].join(',')
|
|
60
|
+
end
|
|
61
|
+
|
|
48
62
|
options = default_json_options(
|
|
49
|
-
name:
|
|
63
|
+
name: name,
|
|
50
64
|
fields: fields,
|
|
65
|
+
only: @render_json_config[:only],
|
|
51
66
|
except: @render_json_config[:except],
|
|
52
67
|
methods: @render_json_config[:methods],
|
|
53
68
|
allowed_methods: @render_json_config[:allowed_methods]
|
|
@@ -55,41 +70,43 @@ module RenderJsonRails
|
|
|
55
70
|
|
|
56
71
|
if includes
|
|
57
72
|
include_options = []
|
|
58
|
-
@render_json_config[:includes]
|
|
59
|
-
if includes.include?(
|
|
60
|
-
includes2 = RenderJsonRails::Concern.includes_for_model(includes: includes, model:
|
|
61
|
-
|
|
62
|
-
include_options << { name => klass.render_json_options(includes: includes2, fields: fields) }
|
|
73
|
+
@render_json_config[:includes]&.each do |model_name, klass|
|
|
74
|
+
if includes.include?(model_name.to_s)
|
|
75
|
+
includes2 = RenderJsonRails::Concern.includes_for_model(includes: includes, model: model_name.to_s)
|
|
76
|
+
include_options << { model_name => klass.render_json_options(includes: includes2, fields: fields) }
|
|
63
77
|
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# includes2 = RenderJsonRails::Concern.includes_for_model(includes: includes, model: 'questions')
|
|
68
|
-
# # raise includes2.inspect + ' ' + includes.inspect
|
|
69
|
-
# include_options << { questions: Organize::Question.render_json_options(includes: includes2, fields: fields) }
|
|
70
|
-
# end
|
|
71
|
-
options[:include] = include_options
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
options[:include] = include_options if include_options.present?
|
|
72
81
|
end
|
|
73
82
|
|
|
74
|
-
options
|
|
75
|
-
end # render_json_options
|
|
76
|
-
# rubocop:enable Lint/UnusedMethodArgument
|
|
83
|
+
options = RenderJsonRails::Concern.deep_meld(options, additional_config) if additional_config
|
|
77
84
|
|
|
85
|
+
options.delete(:methods) if options[:methods].blank?
|
|
78
86
|
|
|
87
|
+
options
|
|
88
|
+
end # render_json_options
|
|
79
89
|
end # class_methods
|
|
80
90
|
|
|
81
91
|
def self.includes_for_model(includes:, model:)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
includes = includes.map { |el| el.gsub(/^#{model}\./, '') if el.start_with?(model + '.') }
|
|
93
|
+
includes.find_all { |el| el.present? }
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.deep_meld(hh1, hh2)
|
|
97
|
+
hh1.deep_merge(hh2) do |_key, this_val, other_val|
|
|
98
|
+
if !this_val.nil? && other_val == nil
|
|
99
|
+
this_val
|
|
100
|
+
elsif this_val == nil && !other_val.nil?
|
|
101
|
+
other_val
|
|
102
|
+
elsif this_val.is_a?(Array) && other_val.is_a?(Array)
|
|
103
|
+
this_val | other_val
|
|
104
|
+
elsif this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
|
105
|
+
deep_meld(this_val, other_val)
|
|
87
106
|
else
|
|
88
|
-
|
|
107
|
+
[this_val, other_val]
|
|
89
108
|
end
|
|
90
109
|
end
|
|
91
|
-
includes.find_all{ |el| el.present? }
|
|
92
|
-
# raise includes.to_json
|
|
93
110
|
end
|
|
94
111
|
end
|
|
95
|
-
end
|
|
112
|
+
end
|
|
@@ -27,7 +27,7 @@ module RenderJsonRails
|
|
|
27
27
|
else
|
|
28
28
|
class_object = object.class
|
|
29
29
|
end
|
|
30
|
-
includes = params[:include].to_s.split(',').map{ |el| el.to_s.strip } if params[:include]
|
|
30
|
+
includes = params[:include].to_s.split(',').map { |el| el.to_s.strip } if params[:include]
|
|
31
31
|
options = class_object.render_json_options(
|
|
32
32
|
includes: includes,
|
|
33
33
|
fields: params[:fields],
|
|
@@ -44,4 +44,4 @@ module RenderJsonRails
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
|
-
end
|
|
47
|
+
end
|
data/render_json_rails.gemspec
CHANGED
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
|
|
10
10
|
spec.summary = "Simle JSON API render like JonApi"
|
|
11
11
|
spec.description = "render json with 'includes' and 'fields' with simple config"
|
|
12
|
-
spec.homepage = "https://
|
|
12
|
+
spec.homepage = "https://github.com/intum/render_json_rails"
|
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
|
14
14
|
|
|
15
15
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
|
@@ -20,10 +20,12 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
|
|
21
21
|
# Specify which files should be added to the gem when it is released.
|
|
22
22
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
23
|
-
spec.files
|
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
24
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
25
25
|
end
|
|
26
26
|
spec.bindir = "exe"
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
28
28
|
spec.require_paths = ["lib"]
|
|
29
|
+
spec.add_development_dependency "activesupport"
|
|
30
|
+
spec.add_development_dependency "byebug"
|
|
29
31
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: render_json_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: '0.2'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marcin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
12
|
-
dependencies:
|
|
11
|
+
date: 2020-10-21 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: byebug
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
13
41
|
description: render json with 'includes' and 'fields' with simple config
|
|
14
42
|
email:
|
|
15
43
|
- marcin@radgost.com
|
|
@@ -18,6 +46,7 @@ extensions: []
|
|
|
18
46
|
extra_rdoc_files: []
|
|
19
47
|
files:
|
|
20
48
|
- ".gitignore"
|
|
49
|
+
- ".rubocop.yml"
|
|
21
50
|
- Gemfile
|
|
22
51
|
- LICENSE.txt
|
|
23
52
|
- README.md
|
|
@@ -29,7 +58,7 @@ files:
|
|
|
29
58
|
- lib/render_json_rails/helper.rb
|
|
30
59
|
- lib/render_json_rails/version.rb
|
|
31
60
|
- render_json_rails.gemspec
|
|
32
|
-
homepage: https://
|
|
61
|
+
homepage: https://github.com/intum/render_json_rails
|
|
33
62
|
licenses:
|
|
34
63
|
- MIT
|
|
35
64
|
metadata: {}
|
|
@@ -48,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
48
77
|
- !ruby/object:Gem::Version
|
|
49
78
|
version: '0'
|
|
50
79
|
requirements: []
|
|
51
|
-
rubygems_version: 3.
|
|
80
|
+
rubygems_version: 3.0.3
|
|
52
81
|
signing_key:
|
|
53
82
|
specification_version: 4
|
|
54
83
|
summary: Simle JSON API render like JonApi
|