rails_api_documentation 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f3a28fb24ee63994ecff8cfdef502e2ee6a07b9
4
- data.tar.gz: c7a0dc69133680aa75d09d0fc2a1cbdd5ace98b3
3
+ metadata.gz: a72e86cdcaefec61dd47079acd6df5eb7ad88762
4
+ data.tar.gz: dc2ee37bbed89765494a3b697ab337db746aaefb
5
5
  SHA512:
6
- metadata.gz: 6a313b7d46410b696f00d7f133d64d385f950c1d56d05ed383d39af1a438d0c2af164b1a064cb7932eeb46f0628dedf8acfacd87daf3af6c7edd0361d5efcf26
7
- data.tar.gz: 4eb52929a55fcc97ab0096246dfd17c5315be9c4255ed4fce52549f2db29a10357f019bc6e5788eb861ea51bef382576980d97d2bedea4bd3adeda2dcc369e65
6
+ metadata.gz: 6a1d84265c02e6c7c588078cb27790bb1a231a6451aa35c3c24210b41a2ec62237deb611be3408346f66dbcd8e68fb6a44f8473194eedb77acc0f4e5e528a085
7
+ data.tar.gz: 43e6fb0376be3a10f0da24cf170bc42110b79869308e5d3b7ebaf19e59104b872e2c34365bc2647ba5e50ab6fb803e38115382579e704f56d4d6692153aeb1d7
data/README.md CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
22
22
  + displaying application api if used in one of correct ways
23
23
  ![alt tag](https://raw.githubusercontent.com/vshaveyko/rails_api_doc/master/preview.png)
24
24
  + Integration with Rabl if it is bundled
25
- + ```resource_params``` method that will filter incoming params for you
25
+ + ```strong_params``` method that will filter incoming params for you
26
26
 
27
27
  ## Usage
28
28
 
@@ -56,7 +56,16 @@ To display api documentation on route '/api_doc' you need to:
56
56
  parameter :comment, type: :string
57
57
  end
58
58
  end
59
- parameter :test, type: String, required: true
59
+ parameter :test, type: :string, required: true
60
+
61
+ parameter({
62
+ articles_attributes: { model: 'Article', type: :ary_object },
63
+ data_attributes: { model: 'Datum' },
64
+ comments_attributes: { model: 'Comment', type: :ary_object }
65
+ }, type: :object) do
66
+ parameter :id
67
+ parameter :name
68
+ end
60
69
 
61
70
  end
62
71
  ```
@@ -75,7 +84,7 @@ To display api documentation on route '/api_doc' you need to:
75
84
 
76
85
  # controller action
77
86
  def create
78
- Comment.create!(resource_params)
87
+ Comment.create!(strong_params)
79
88
  end
80
89
 
81
90
  ```
@@ -84,6 +93,52 @@ To display api documentation on route '/api_doc' you need to:
84
93
 
85
94
  Comment will be created with: `Comment(body='Comment body', title='Comment title', age=nil)`
86
95
 
96
+ ## Value
97
+
98
+ You can pass optional value argument to every parameter:
99
+
100
+ ```ruby
101
+ parameter :val, type: :integer, value: -> (request_value) { 5 }
102
+ ```
103
+
104
+ on every matching request value in this field will be overriden by value returned by proc.
105
+
106
+ value field expecting anything that will respond to `:call` and can accept one argument(param value from request)
107
+
108
+ you should expect that value passed can be `nil`
109
+
110
+ This can be used to force values on some fields, or modify values passed to request in some ways.
111
+
112
+ E.g. you want to force current_user_id on model creation instead of passing it from frontend.
113
+
114
+ ## Enum
115
+
116
+ When you defined parameter type as `:enum` you can pass `enum:` option. This will filter parameter by values provided.
117
+
118
+ ## Group common blocks
119
+
120
+ You can define parameters that have common fields this way:
121
+
122
+ ```ruby
123
+ parameter({
124
+ articles_attributes: { model: 'Article', type: :ary_object },
125
+ data_attributes: { model: 'Datum' },
126
+ comments_attributes: { model: 'Comment', type: :ary_object }
127
+ }, type: :object) do
128
+ parameter :id
129
+ parameter :name
130
+ end
131
+ ```
132
+
133
+ Pass common values as last optional arguments and uniq definitions as hash value.
134
+ All nesting parameters are applied to elements in blocks.
135
+
136
+ Something with same type can be defined like this:
137
+
138
+ ```ruby
139
+ parameter :name, :desc, type: :string
140
+ ```
141
+
87
142
  ## Types
88
143
 
89
144
  Parameter type may be one of these:
@@ -2,4 +2,4 @@
2
2
 
3
3
  div[id="#{ctrl}.request" style="--row-count: #{request_headers.length}"]
4
4
 
5
- = render 'shared/table', model: ctrl, rows: repo[ctrl], headers: request_headers, nesting: [], params: { api_type: :request }
5
+ = render 'shared/table', model: ctrl, rows: repo[ctrl.name], headers: request_headers, nesting: [], params: { api_type: :request }
@@ -11,6 +11,6 @@ div.response-table[id="#{ctrl}.response" style="--row-count: #{response_headers
11
11
  div.request-action-title
12
12
  = render 'shared/title', locals: { blue_title: route[:method], yellow_title: route[:url]}
13
13
 
14
- - if rows = repo.load_template(ctrl, action)
14
+ - if rows = repo.load_attrs(ctrl, action)
15
15
 
16
16
  = render 'shared/table', model: ctrl, rows: rows, headers: response_headers, nesting: [], params: { api_action: action, api_type: :response }
@@ -29,7 +29,7 @@ div.flex-table
29
29
  - if index.zero?
30
30
  span.ico ✏
31
31
  / = submit_tag ,name: 'destroy', class: 'ico destroy'
32
- = link_to '❌' , api_doc_url(construct_destroy_param(row_values, params, nesting)), method: :delete, class: 'destroy ico'
32
+ = link_to '❌' , api_doc_url(construct_destroy_param(row_values, params, nesting)), method: :delete,data: { confirm: 'Are you sure?' }, class: 'destroy ico'
33
33
  span.exit.ico ❌
34
34
  = submit_tag '✔'
35
35
 
@@ -5,19 +5,48 @@ module RailsApiDoc
5
5
  module Request
6
6
  module DSL
7
7
 
8
+ #
8
9
  # Use parameter in controller to define REQUEST parameter.
9
10
  # Adds it to repository: RailsApiDoc::Controller::Request::Repository
10
- def parameter(name, options = {}, &block)
11
+ # Params can be defined in several ways:
12
+ # 1. parameter :name, type: :string
13
+ #
14
+ # 2. parameter {
15
+ # dose_form_attributes: { model: 'Rxnorm::RxDoseForm' },
16
+ # input_method_attributes: { model: 'TreatmentInfo::InputMethod' },
17
+ # input_condition_attributes: { model: 'Drugs::InputCondition' },
18
+ # input_duration_attributes: { model: 'Drugs::InputDuration' }
19
+ # }, type: :object do
20
+ # parameter :id
21
+ # parameter :name
22
+ # end
23
+ #
24
+ # 3. parameter :name, :code, type: :string
25
+ #
26
+ def parameter(*arguments, &block)
27
+ options = arguments.extract_options!
28
+
11
29
  raise ArgumentError, 'Parameter already defined.' if repo.key?(name)
12
30
 
13
31
  validate_options(options, block_given?)
14
32
 
15
- define_parameter(name, options, &block)
33
+ arguments.each do |param|
34
+ # 2)
35
+ if param.is_a?(Hash)
36
+ param.each do |param_name, additional_options|
37
+ _options = options.merge(additional_options)
38
+
39
+ define_parameter(param_name, _options, &block)
40
+ end
41
+ else # 1), 3)
42
+ define_parameter(param, options, &block)
43
+ end
44
+ end
16
45
  end
17
46
 
18
47
  private
19
48
 
20
- def validate_options(options, block_given)
49
+ def validate_options(options, _block_given)
21
50
  options.assert_valid_keys(RailsApiDoc::Controller::Param::VALID_KEYS)
22
51
 
23
52
  RailsApiDoc::Controller::Request::Param.valid_type?(options[:type])
@@ -4,11 +4,11 @@ class RailsApiDoc::Controller::Request::Factory
4
4
  class << self
5
5
 
6
6
  def repo
7
- attributes = RailsApiDoc::Controller::Request::Repository.new
7
+ repo = RailsApiDoc::Controller::Request::Repository.new
8
8
 
9
- attributes = merge_attributes_from_model attributes
9
+ repo.repo = merge_attributes_from_model repo.repo
10
10
 
11
- attributes
11
+ repo
12
12
  end
13
13
 
14
14
  def registered_controllers
@@ -21,7 +21,7 @@ class RailsApiDoc::Controller::Request::Factory
21
21
  # do not mutate attributes
22
22
  #
23
23
  def merge_attributes_from_model(attributes)
24
- RailsApiDoc::Model::AttributeMerger.new(attributes).call(api_type: 'request')
24
+ RailsApiDoc::Model::AttributeMerger.new(attributes, 'request').call
25
25
  end
26
26
 
27
27
  end
@@ -50,9 +50,9 @@ module RailsApiDoc
50
50
 
51
51
  def display_special
52
52
  spec = if enum?
53
- enum
54
- elsif nested?
55
- model
53
+ enum
54
+ elsif nested? || model?
55
+ model
56
56
  end
57
57
 
58
58
  spec = spec.to_s + "(#{param.special})" if param&.special
@@ -8,11 +8,7 @@ class RailsApiDoc::Controller::Response::Factory
8
8
  # TODO: add more options later depending on app settings
9
9
  # TODO: rename to :load_repo
10
10
  def repo
11
- attributes = RailsApiDoc::Controller::Response::Repository.new(repository.repo)
12
-
13
- attributes = merge_attributes_from_model attributes
14
-
15
- attributes
11
+ RailsApiDoc::Controller::Response::Repository.new(repository.repo)
16
12
  end
17
13
 
18
14
  def controllers
@@ -25,13 +21,6 @@ class RailsApiDoc::Controller::Response::Factory
25
21
  @repo ||= ::RailsApiDoc::Controller::Response::Rabl.new(controllers)
26
22
  end
27
23
 
28
- #
29
- # do not mutate attributes
30
- #
31
- def merge_attributes_from_model(attributes)
32
- RailsApiDoc::Model::AttributeMerger.new(attributes).call(api_type: 'response')
33
- end
34
-
35
24
  end
36
25
 
37
26
  end
@@ -7,7 +7,6 @@ module RailsApiDoc::Controller::Response::Headers
7
7
 
8
8
  RESPONSE_HEADERS = [
9
9
  NAME_HEADER,
10
- TYPE_HEADER,
11
10
  VALUE_HEADER,
12
11
  DESC_HEADER
13
12
  ].reduce(&:merge).freeze
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # author: Vadim Shaveiko <@vshaveyko>
1
3
  # :nodoc:
2
4
  class RailsApiDoc::Controller::Response::Repository
3
5
 
@@ -5,7 +7,15 @@ class RailsApiDoc::Controller::Response::Repository
5
7
  include RailsApiDoc::Controller::Response::Headers
6
8
 
7
9
  def initialize(repo)
8
- @repo = repo.clone.transform_values { |v| v.deep_dup }
10
+ @repo = repo.clone.transform_values(&:deep_dup)
11
+ end
12
+
13
+ def load_attrs(ctrl, action)
14
+ at = load_template(ctrl, action)&.nodes || {}
15
+
16
+ at = RailsApiDoc::Model::AttributeMerger.new(at, 'response').merge_action(action: action, ctrl: ctrl)
17
+
18
+ at
9
19
  end
10
20
 
11
21
  def load_template(ctrl, action)
@@ -1,14 +1,19 @@
1
- # :nodoc:
1
+ # frozen_string_literal: true
2
+ # author: Vadim Shaveiko <@vshaveyko>
2
3
  module RailsApiDoc
3
4
  module Controller
4
5
  module ResourceParams
5
- module DSL
6
+ module DSL # :nodoc:
6
7
 
7
8
  include RailsApiDoc::Controller::ResourceParams::PermittedParams # implements params_to_permit
8
9
 
9
- def resource_params
10
+ def strong_params(pars = params)
11
+ #
10
12
  # accepted_params for permit
11
- params.permit(params_to_permit)
13
+ #
14
+ permitted = params_to_permit(pars)
15
+
16
+ pars.permit(permitted)
12
17
  end
13
18
 
14
19
  end
@@ -7,8 +7,8 @@ module RailsApiDoc
7
7
 
8
8
  private
9
9
 
10
- def params_to_permit
11
- _next_nesting_level(params, param_data: _permitted_params)
10
+ def params_to_permit(pars = params)
11
+ _next_nesting_level(pars, param_data: _permitted_params)
12
12
  end
13
13
 
14
14
  def _permitted_params
@@ -32,7 +32,6 @@ module RailsApiDoc
32
32
  level_accepted_params
33
33
  end
34
34
 
35
-
36
35
  #
37
36
  # loop through current level of params and add to permit level if all requirements are met
38
37
  #
@@ -47,6 +46,10 @@ module RailsApiDoc
47
46
  #
48
47
  def loop_params(params, level_permitted_params, accepted_params)
49
48
  level_permitted_params.each do |param_name, api_param_data|
49
+ if api_param_data.value&.respond_to?(:call)
50
+ params[param_name] = api_param_data.value.call(params[param_name])
51
+ end
52
+
50
53
  controller_param = params[param_name]
51
54
 
52
55
  _check_required(param_name, controller_param, api_param_data) # raise if required and no value
@@ -63,7 +66,6 @@ module RailsApiDoc
63
66
  param_data: api_param_data.nested,
64
67
  current_accepted_params: accepted_params,
65
68
  param_name: param_name)
66
-
67
69
  end
68
70
  elsif api_param_data.nested? # value should be nested object
69
71
  _next_nesting_level(controller_param,
@@ -6,53 +6,58 @@ class RailsApiDoc::Model::AttributeMerger
6
6
  MODEL = RailsApiDoc::ApiDatum
7
7
  MERGABLE_FIELDS = [:type, :desc, :action_type].freeze
8
8
 
9
+ @@data = MODEL.all
10
+
9
11
  #
10
12
  # do not mutate attributes
11
13
  #
12
14
  # please - impossible
13
15
  #
14
- def initialize(attributes)
15
- @attrs = attributes
16
+ def initialize(attributes, api_type)
17
+ @attrs = attributes.stringify_keys
18
+ @api_type = api_type
16
19
  end
17
20
 
18
- def call(api_type:)
19
- @api_type = api_type
21
+ def merge_action(action:, ctrl:)
22
+ merge_data = @@data.select { |d| d.api_type == @api_type && d.api_action == action.to_s && d.nesting.first == ctrl.name }
20
23
 
21
- api_params = MODEL.where(api_type: api_type).all.each do |param|
22
- _add_nested_param(param)
24
+ merge_data.each do |param|
25
+ _add_nested_param(param, param.nesting[1..-1], @attrs)
23
26
  end
24
27
 
25
28
  @attrs
26
29
  end
27
30
 
28
- private
31
+ def call
32
+ api_params = @@data.select { |d| d.api_type == @api_type }.each do |param|
33
+ #
34
+ # nesting should be present for parameter to appear
35
+ #
36
+ next unless param.name && param.nesting.present?
29
37
 
30
- def _add_nested_param(param)
31
- # nesting should be present for parameter to appear
32
- return if param.nesting.blank?
38
+ attrs, nesting, name = _parse_settings(param)
33
39
 
34
- attrs, nesting, name = _parse_settings(param)
40
+ _add_nested_param(param, nesting, attrs)
41
+ end
35
42
 
36
- return unless name
43
+ @attrs
44
+ end
45
+
46
+ private
37
47
 
38
- ctrl_param = _find_param(nesting, name, attrs)
48
+ def _add_nested_param(param, nesting, attrs)
49
+ ctrl_param = _find_param(nesting, param.name, attrs)
39
50
 
40
51
  ctrl_param.param = param
41
52
  # _merge_data_to_param(ctrl_param, param)
42
53
  end
43
54
 
44
55
  def _parse_settings(param)
45
- ctrl = param.nesting[0].constantize
56
+ ctrl = param.nesting[0]
46
57
  nesting = param.nesting[1..-1]
47
58
  name = param.name&.to_sym
48
59
  attrs = @attrs[ctrl]
49
60
 
50
- #
51
- # making exception
52
- # until request parameters are not split by actions
53
- #
54
- attrs = attrs[param.api_action] if @api_type == 'response'
55
-
56
61
  [attrs, nesting, name]
57
62
  end
58
63
 
@@ -82,18 +87,18 @@ class RailsApiDoc::Model::AttributeMerger
82
87
  end
83
88
  end
84
89
 
85
- def _find_param(nesting, name, attrs)
86
- nesting.each do |model|
87
- nested_attrs = attrs.each_value.detect { |v| v.nested? && v.model == model }
90
+ def _find_param(nest, name, attrs)
91
+ nest.each do |model|
92
+ #
93
+ # model on different fields because of wrong nesting sturcture for request
94
+ # TODO: fix this later
95
+ #
96
+ nested_attrs = attrs.detect { |k, v| v.nested? && (v.model == model || k.to_s == model) }
88
97
 
89
98
  attrs = nested_attrs ? nested_attrs : _define_nesting_level(attrs, name, model)
90
99
  end
91
100
 
92
- if attrs[name]
93
- attrs[name]
94
- else
95
- attrs[name] = _init_param_for_api_type(name)
96
- end
101
+ attrs[name] ||= _init_param_for_api_type(name, {})
97
102
  end
98
103
 
99
104
  def _define_nesting_level(attrs, name, model)
@@ -123,7 +128,7 @@ class RailsApiDoc::Model::AttributeMerger
123
128
  if @api_type == 'request'
124
129
  RailsApiDoc::Controller::Request::Param.new(name, options, is_new: true)
125
130
  elsif @api_type == 'response'
126
- RailsApiDoc::Controller::Response::Param.new(name, name, options[:nested], options[:model], '', options[:type], is_new: true)
131
+ RailsApiDoc::Controller::Response::Param.new(name, name, options[:nested], options[:model], nil, options[:type], is_new: true)
127
132
  end
128
133
  end
129
134
 
@@ -18,6 +18,7 @@ class RailsApiDoc::Model::AttributeParser
18
18
  action_type: params[:action],
19
19
  nesting: params[:nesting],
20
20
  api_type: params[:api_type],
21
+ api_action: params[:api_action],
21
22
  id: params[:id]
22
23
  }.compact
23
24
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  # author: Vadim Shaveiko <@vshaveyko>
3
3
  module RailsApiDoc
4
- VERSION = '0.3.1'
4
+ VERSION = '0.3.2'
5
5
  end
data/lib/rails_api_doc.rb CHANGED
@@ -1,9 +1,10 @@
1
1
  # author: Vadim Shaveiko <@vshaveyko>
2
2
  # frozen_string_literal: true
3
3
  module RailsApiDoc
4
- NESTED_TYPES = [:ary_object, :object, :model].freeze
4
+
5
+ NESTED_TYPES = [:ary_object, :object, :json].freeze
5
6
 
6
- STRAIGHT_TYPES = [:bool, :string, :integer, :array, :datetime, :enum].freeze
7
+ STRAIGHT_TYPES = [:bool, :string, :integer, :array, :datetime, :enum, :model].freeze
7
8
 
8
9
  ACCEPTED_TYPES = (NESTED_TYPES + STRAIGHT_TYPES).freeze
9
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_api_documentation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - vs
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-12 00:00:00.000000000 Z
11
+ date: 2016-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler