decanter 3.3.0 → 3.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7ee762570171d13eede776ea7715f54e3daa9228e09b8a83f278c857eaeb04c
4
- data.tar.gz: 4dee8cfa404faeb3362925832d53b4e55c0f82cddd2427416c0fdf79a66ff85e
3
+ metadata.gz: 033f0c72ec50bb90c9853ffe63ebc76b8a887431535b8df3b9a16e1525d57962
4
+ data.tar.gz: 6fa983058d3a8d1c1df2285ef931ff0f9c271b7c8f43cdafa78ebf9119911ca2
5
5
  SHA512:
6
- metadata.gz: dd1b076ac0cbe78783ab19b4ae43d8fb7d87bd46b76155ec08dcbdfb55638415667c1ad19ccdeff4f81e0b0482c2ef32292a1686df648ee52e0b3ce4824ea069
7
- data.tar.gz: d34c06b627f4c1b4773829cd9e3003f3a8eb167a97acfa55be361628078d8230d8be1664d576d49eb6de9705d56f95c478ff52c56c2c656b1882d167df69e499
6
+ metadata.gz: 5551658bbbf3d094a1d04e8154133b707b802cb314f291f1bc70f5cd224964b85a70a583a104553ee4e246cb2673f3d36b5d65e4991c0fb4d41d9771e26192be
7
+ data.tar.gz: 343bdd635126c2ba52cb8cb27a0610104ac54d921f047137cce465ae908e48d473260c1d358d5e695dec10fff8334c173962e438d18cb0f373bf8138643c0aec
@@ -33,4 +33,4 @@ For any non-trivial change, we prefer an issue to be created first. This helps u
33
33
  ### Sending a Pull Request
34
34
  If this is your first Pull Request, we recommend learning how to navigate GitHub via this free video tutorial: [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github).
35
35
 
36
- The LaunchPad Lab team monitors this repository for pull requests. Once a pull request has been created from a forked repository that **meets all the guidelines** outlined in the [Pull Request Checklist](.github/PULL_REQUEST_TEMPLATE.md), we will review the request and either merge it, request changes, or close it with an explanation. We aim to respond to pull requests within 48 hours.
36
+ The LaunchPad Lab team monitors this repository for pull requests. Once a pull request has been created from a forked repository that **meets all the guidelines** outlined in the [Pull Request Checklist](.github/PULL_REQUEST_TEMPLATE.md), we will review the request and either merge it, request changes, or close it with an explanation. We aim to respond to pull requests within 48 hours.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- decanter (3.3.0)
4
+ decanter (3.4.0)
5
5
  actionpack (>= 4.2.10)
6
6
  activesupport (~> 5.2)
7
7
  rails-html-sanitizer (>= 1.0.4)
data/README.md CHANGED
@@ -15,6 +15,7 @@ gem 'decanter', '~> 3.0'
15
15
  - [Basic Usage](#basic-usage)
16
16
  - [Decanters](#decanters)
17
17
  - [Generators](#generators)
18
+ - [Decanting Collections](#decanting-collections)
18
19
  - [Nested resources](#nested-resources)
19
20
  - [Default parsers](#default-parsers)
20
21
  - [Parser options](#parser-options)
@@ -70,6 +71,37 @@ rails g decanter Trip name:string start_date:date end_date:date
70
71
  rails g parser TruncatedString
71
72
  ```
72
73
 
74
+ ### Decanting Collections
75
+
76
+ Decanter can decant a collection of a resource, applying the patterns used in the [fast JSON API gem](https://github.com/Netflix/fast_jsonapi#collection-serialization):
77
+
78
+ ```rb
79
+ # app/controllers/trips_controller.rb
80
+
81
+ def create
82
+ trip_params = {
83
+ trips: [
84
+ { name: 'Disney World', start_date: '12/24/2018', end_date: '12/28/2018' },
85
+ { name: 'Yosemite', start_date: '5/1/2017', end_date: '5/4/2017' }
86
+ ]
87
+ }
88
+ decanted_trip_params = TripDecanter.decant(trip_params[:trips])
89
+ Trip.create(decanted_trip_params) # bulk create trips with decanted params
90
+ end
91
+ ```
92
+
93
+ #### Control Over Decanting Collections
94
+
95
+ You can use the `is_collection` option for explicit control over decanting collections.
96
+
97
+ `decanted_trip_params = TripDecanter.decant(trip_params[:trips], is_collection: true)`
98
+
99
+ If this option is not provided, autodetect logic is used to determine if the providing incoming params holds a single object or collection of objects.
100
+
101
+ - `nil` or not provided: will try to autodetect single vs collection
102
+ - `true` will always treat the incoming params args as *collection*
103
+ - `false` will always treat incoming params args as *single object*
104
+
73
105
  ### Nested resources
74
106
 
75
107
  Decanters can declare relationships using `ActiveRecord`-style declarators:
@@ -8,7 +8,6 @@ module Decanter
8
8
  end
9
9
 
10
10
  module ClassMethods
11
-
12
11
  def input(name, parsers=nil, **options)
13
12
  # Convert all input names to symbols to correctly calculate handled vs. unhandled keys
14
13
  input_names = [name].flatten.map(&:to_sym)
@@ -20,7 +20,6 @@ module Decanter
20
20
  end
21
21
 
22
22
  module ClassMethods
23
-
24
23
  def decant_create(args, **options)
25
24
  self.new(decant(args, options))
26
25
  .save(context: options[:context])
@@ -36,12 +35,28 @@ module Decanter
36
35
  end
37
36
 
38
37
  def decant(args, options={})
38
+ is_collection?(args, options[:is_collection]) ? decant_collection(args, options) : decant_args(args, options)
39
+ end
40
+
41
+ def decant_collection(args, options)
42
+ args.map { |resource| decant_args(resource, options) }
43
+ end
44
+
45
+ def decant_args(args, options)
39
46
  if specified_decanter = options[:decanter]
40
47
  Decanter.decanter_from(specified_decanter)
41
48
  else
42
49
  Decanter.decanter_for(self)
43
50
  end.decant(args)
44
51
  end
52
+
53
+ private
54
+
55
+ # leveraging the approach used in the [fast JSON API gem](https://github.com/Netflix/fast_jsonapi#collection-serialization)
56
+ def is_collection?(args, collection_option=nil)
57
+ return collection_option[:is_collection] unless collection_option.nil?
58
+ args.respond_to?(:size) && !args.respond_to?(:each_pair)
59
+ end
45
60
  end
46
61
 
47
62
  module ActiveRecordExtensions
@@ -1,3 +1,3 @@
1
1
  module Decanter
2
- VERSION = '3.3.0'.freeze
2
+ VERSION = '3.4.0'.freeze
3
3
  end
@@ -2,12 +2,12 @@ module Rails
2
2
  module Generators
3
3
  class DecanterGenerator < NamedBase
4
4
  source_root File.expand_path('../templates', __FILE__)
5
- check_class_collision :suffix => 'Decanter'
5
+ check_class_collision suffix: 'Decanter'
6
6
  ASSOCIATION_TYPES = [:has_many, :has_one, :belongs_to]
7
7
 
8
- argument :attributes, :type => :array, :default => [], :banner => 'field:type field:type'
8
+ argument :attributes, type: :array, default: [], banner: 'field:type field:type'
9
9
 
10
- class_option :parent, :type => :string, :desc => 'The parent class for the generated decanter'
10
+ class_option :parent, type: :string, desc: 'The parent class for the generated decanter'
11
11
 
12
12
  def create_decanter_file
13
13
  template 'decanter.rb.erb', File.join('app/decanters', class_path, "#{file_name}_decanter.rb")
@@ -2,9 +2,9 @@ module Rails
2
2
  module Generators
3
3
  class ParserGenerator < NamedBase
4
4
  source_root File.expand_path('../templates', __FILE__)
5
- check_class_collision :suffix => 'Parser'
5
+ check_class_collision suffix: 'Parser'
6
6
 
7
- class_option :parent, :type => :string, :desc => 'The parent class for the generated parser'
7
+ class_option :parent, type: :string, desc: 'The parent class for the generated parser'
8
8
 
9
9
  def create_parser_file
10
10
  template 'parser.rb.erb', File.join('lib/decanter/parsers', class_path, "#{file_name}_parser.rb")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decanter
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Francis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-11-03 00:00:00.000000000 Z
12
+ date: 2020-11-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack