mailchimp_api_v3 0.0.5 → 0.0.6

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: fb3dc62663ec203d2d9e0c0a90bead5dd237422c
4
- data.tar.gz: 152265412ea8717fecf81db4477cd98e133e08c3
3
+ metadata.gz: d8f048d1673768ca49fb00ab3a0b8965c16a8a60
4
+ data.tar.gz: 98310035ec6e4de642b1d1df78aa1676e7185a53
5
5
  SHA512:
6
- metadata.gz: 1374abb4143591b1eba1e9698fe116360595298b76a89fd257230e5496282a5b429b0d1a90ba62f53188e179efe17107a4677a04b5ea26b821ff20da6db91451
7
- data.tar.gz: acd6b8b0ca5bbac91b6e2158ea267d5d82faff46da2d3943a55d8715e3cca9dea4d9dc8f9b2b56d228654f88784ac8ab9609209b601bf41961e9ce58da734e28
6
+ metadata.gz: f412aafb47730c2e7c5f4f2ac54586261758bcdec8ad8690fef9e3b6b88a6438ebe1781a2df3ffa25025aee18b1d3eb13c3cb697e9f1a641ac8f0ef121e8c699
7
+ data.tar.gz: d207f73778a05e6ef54b66884c3d80989a3c3d42ef16263c401767fad0a4af7a52a2e681ac3fbefa8cda3f605517d6ca1ed6c0fa1c2e0cc76dc16b6ed5214092
data/.rubocop.yml CHANGED
@@ -24,3 +24,16 @@ FileName:
24
24
  LineLength:
25
25
  Max: 120
26
26
  Enabled: true
27
+
28
+ Style/SymbolArray:
29
+ Description: 'Use %i or %I for arrays of symbols.'
30
+ StyleGuide: 'https://github.com/bbatsov/ruby-style-guide#percent-i'
31
+ Enabled: false # Only available in Ruby 2.0+
32
+
33
+ Style/ExtraSpacing:
34
+ Description: 'Do not use unnecessary spacing.'
35
+ Enabled: true
36
+
37
+ Lint/LiteralInInterpolation:
38
+ Description: 'Avoid interpolating literals in strings'
39
+ AutoCorrect: true
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  ## Mailchimp API v3
2
+ [![Gem Version](https://badge.fury.io/rb/mailchimp_api_v3.svg)](https://rubygems.org/gems/mailchimp_api_v3)
3
+ [![Gem downloads](https://img.shields.io/gem/dt/mailchimp_api_v3.svg)](https://rubygems.org/gems/mailchimp_api_v3)
4
+ [![Build status](https://img.shields.io/circleci/project/Xenapto/mailchimp_api_v3/develop.svg)](https://circleci.com/gh/Xenapto/mailchimp_api_v3)
5
+ [![Code quality](http://img.shields.io/codeclimate/github/Xenapto/mailchimp_api_v3.svg?style=flat)](https://codeclimate.com/github/Xenapto/mailchimp_api_v3)
6
+ [![Coverage](https://img.shields.io/coveralls/Xenapto/mailchimp_api_v3/develop.svg?style=flat)](https://coveralls.io/r/Xenapto/mailchimp_api_v3?branch=develop)
7
+ [![Dependency Status](https://gemnasium.com/Xenapto/mailchimp_api_v3.svg)](https://gemnasium.com/Xenapto/mailchimp_api_v3)
2
8
 
3
- [![](http://img.shields.io/gem/v/mailchimp_api_v3.svg?style=flat)](https://rubygems.org/gems/mailchimp_api_v3)
4
- [![](https://img.shields.io/circleci/project/Xenapto/mailchimp_api_v3/develop.svg)](https://circleci.com/gh/Xenapto/mailchimp_api_v3)
5
- [![](http://img.shields.io/codeclimate/github/Xenapto/mailchimp_api_v3.svg?style=flat)](https://codeclimate.com/github/Xenapto/mailchimp_api_v3)
6
- [![](https://img.shields.io/coveralls/Xenapto/mailchimp_api_v3/develop.svg?style=flat)](https://coveralls.io/r/Xenapto/mailchimp_api_v3?branch=develop)
7
- [![](http://img.shields.io/badge/developer-awesome-brightgreen.svg?style=flat)](http://xenapto.com)
8
-
9
- A simple gem to interact with Mailchimp through their API v3
9
+ A simple gem to interact with Mailchimp through the Mailchimp API v3
10
10
 
11
11
  ### Project status
12
12
 
@@ -30,7 +30,7 @@ Or install it yourself as:
30
30
 
31
31
  ### Usage
32
32
 
33
- The Mailchimp API documentation is here: http://kb.mailchimp.com/api. Their suggstions for subscriber management are here: http://kb.mailchimp.com/api/article/how-to-manage-subscribers.
33
+ The Mailchimp API documentation is here: http://kb.mailchimp.com/api. Their suggestions for subscriber management are here: http://kb.mailchimp.com/api/article/how-to-manage-subscribers.
34
34
 
35
35
  To connect to the Mailchimp API you need to supply an API key. You can do this explicitly when you connect, or you can set an environment variable `MAILCHIMP_API_KEY`.
36
36
 
@@ -54,10 +54,13 @@ list = mailchimp.lists.find_by name: 'My first list'
54
54
  mailchimp = Mailchimp.connect
55
55
  member = mailchimp.lists('e73f5910ca').members('ann@example.com')
56
56
  member.name # => "Ann Example"
57
+ member.update last_name: 'Williams'
57
58
  ```
58
59
 
59
60
  ### Contributing
60
61
 
62
+ [![Developer](http://img.shields.io/badge/developer-awesome-brightgreen.svg?style=flat)](http://xenapto.com)
63
+
61
64
  1. Fork it
62
65
  1. Create your feature branch (`git checkout -b my-new-feature`)
63
66
  1. Commit your changes (`git commit -am 'Add some feature'`)
@@ -1,7 +1,5 @@
1
1
  module Mailchimp
2
- class Account
3
- include Instance::InstanceMethods
4
-
2
+ class Account < Instance
5
3
  def id
6
4
  account_id
7
5
  end
@@ -1,8 +1,8 @@
1
- require 'mailchimp_api_v3/exception'
2
1
  require 'mailchimp_api_v3/collection'
3
2
  require 'mailchimp_api_v3/instance'
3
+ require 'mailchimp_api_v3/exception'
4
4
  require 'mailchimp_api_v3/account'
5
- require 'mailchimp_api_v3/lists'
5
+ require 'mailchimp_api_v3/list'
6
6
  require 'mailchimp_api_v3/client/remote'
7
7
 
8
8
  module Mailchimp
@@ -1,7 +1,6 @@
1
- require 'mailchimp_api_v3/collection/paging'
2
-
3
1
  module Mailchimp
4
- module Collection
2
+ class Collection < Array
3
+ require 'mailchimp_api_v3/collection/paging' # Don't require before class inherits from Array
5
4
  include Paging
6
5
 
7
6
  def initialize(client, parent_path = '', options = {})
@@ -17,7 +16,7 @@ module Mailchimp
17
16
  end
18
17
 
19
18
  def path
20
- @path ||= "#{@parent_path}/#{self.class.path_key}"
19
+ @path ||= "#{@parent_path}/#{self.class::PATH_KEY}"
21
20
  end
22
21
 
23
22
  def where(data, limit = nil)
@@ -40,7 +39,7 @@ module Mailchimp
40
39
 
41
40
  def create(data)
42
41
  response = @client.post data, path
43
- self.class.child_class.new @client, response, path
42
+ self.class::CHILD_CLASS.new @client, response, path
44
43
  end
45
44
 
46
45
  def first_or_create(data)
@@ -1,5 +1,5 @@
1
1
  module Mailchimp
2
- module Collection
2
+ class Collection
3
3
  module Paging
4
4
  DEFAULT_PAGE_SIZE = 500
5
5
 
@@ -9,21 +9,21 @@ module Mailchimp
9
9
  end
10
10
 
11
11
  def fetch_options
12
- links_delim = self.class.data_key.empty? ? '' : '.'
12
+ links_delim = self.class::DATA_KEY.empty? ? '' : '.'
13
13
 
14
14
  {
15
- 'exclude_fields' => "#{self.class.data_key}#{links_delim}_links",
15
+ 'exclude_fields' => "#{self.class::DATA_KEY}#{links_delim}_links",
16
16
  'offset' => offset,
17
17
  'count' => page_size
18
18
  }
19
19
  end
20
20
 
21
21
  def page_array
22
- @page_array ||= page[self.class.data_key]
22
+ @page_array ||= page[self.class::DATA_KEY]
23
23
  end
24
24
 
25
25
  def page_children
26
- @page_children ||= page_array.map { |d| self.class.child_class.new @client, d, path }
26
+ @page_children ||= page_array.map { |d| self.class::CHILD_CLASS.new @client, d, path }
27
27
  end
28
28
 
29
29
  def offset
@@ -23,22 +23,11 @@ module Mailchimp
23
23
  end
24
24
  end
25
25
 
26
- class APIKeyError < DataException
27
- end
28
-
29
- class Duplicate < DataException
30
- end
31
-
32
- class MissingField < DataException
33
- end
34
-
35
- class BadRequest < DataException
36
- end
37
-
38
- class UnknownAttribute < RuntimeError
39
- end
40
-
41
- class MissingId < RuntimeError
42
- end
26
+ APIKeyError = Class.new(DataException)
27
+ Duplicate = Class.new(DataException)
28
+ MissingField = Class.new(DataException)
29
+ BadRequest = Class.new(DataException)
30
+ UnknownAttribute = Class.new(RuntimeError)
31
+ MissingId = Class.new(RuntimeError)
43
32
  end
44
33
  end
@@ -1,62 +1,62 @@
1
1
  module Mailchimp
2
- module Instance
3
- module InstanceMethods
4
- def initialize(client, data, collection_path = '')
5
- @client = client
6
- @collection_path = collection_path
7
- @data = data
8
- #- puts @data # debug
9
- end
10
-
11
- def update(new_data)
12
- @data = @client.patch(new_data, path)
13
- self
14
- end
2
+ class Instance
3
+ # Class methods
15
4
 
16
- def path
17
- @path ||= "#{@collection_path}/#{@data['id']}"
18
- end
5
+ def self.get(client, collection_path, id)
6
+ data = client.get "#{collection_path}/#{id}"
7
+ new client, data, collection_path
8
+ end
19
9
 
20
- def matches?(match_data)
21
- match_data.each do |k, v|
22
- break false unless __send__(k).casecmp(v).zero? # case-insensitive comparison
23
- true
24
- end
25
- end
10
+ # Instance methods
26
11
 
27
- def subclass_from(collection_class, options = {})
28
- if options.is_a? String
29
- # Use it as an id for an instance
30
- child_path = "#{path}/#{collection_class.path_key}"
31
- collection_class.child_class.get @client, child_path, options
32
- else
33
- # Get the collection
34
- collection_class.new @client, path, options
35
- end
36
- end
12
+ def initialize(client, data, collection_path = '')
13
+ @client = client
14
+ @collection_path = collection_path
15
+ @data = data
16
+ #- puts @data # debug
17
+ end
37
18
 
38
- private
19
+ def update(new_data)
20
+ @data = @client.patch(new_data, path)
21
+ self
22
+ end
39
23
 
40
- attr_reader :data
24
+ def path
25
+ @path ||= "#{@collection_path}/#{@data['id']}"
26
+ end
41
27
 
42
- def method_missing(symbol, options = {})
43
- key = symbol.id2name
44
- fail_unless_exists key, options
45
- @data[key]
28
+ def matches?(match_data)
29
+ match_data.each do |k, v|
30
+ break false unless __send__(k).casecmp(v).zero? # case-insensitive comparison
31
+ true
46
32
  end
33
+ end
47
34
 
48
- def fail_unless_exists(key, options = {})
49
- return if @data.key? key
50
- message = options == {} ? key : "#{key}: #{options}"
51
- fail Mailchimp::Exception::UnknownAttribute, message
35
+ def subclass_from(collection_class, options = {})
36
+ if options.is_a? String
37
+ # Use it as an id for an instance
38
+ child_path = "#{path}/#{collection_class::PATH_KEY}"
39
+ collection_class::CHILD_CLASS.get @client, child_path, options
40
+ else
41
+ # Get the collection
42
+ collection_class.new @client, path, options
52
43
  end
53
44
  end
54
45
 
55
- module ClassMethods
56
- def get(client, collection_path, id)
57
- data = client.get "#{collection_path}/#{id}"
58
- new client, data, collection_path
59
- end
46
+ private
47
+
48
+ attr_reader :data
49
+
50
+ def method_missing(symbol, options = {})
51
+ key = symbol.id2name
52
+ fail_unless_exists key, options
53
+ @data[key]
54
+ end
55
+
56
+ def fail_unless_exists(key, options = {})
57
+ return if @data.key? key
58
+ message = options == {} ? key : "#{key}: #{options}"
59
+ fail Mailchimp::Exception::UnknownAttribute, message
60
60
  end
61
61
  end
62
62
  end
@@ -1,9 +1,11 @@
1
1
  module Mailchimp
2
2
  class List
3
3
  class InterestCategory
4
- class Interest
5
- include Instance::InstanceMethods
6
- extend Instance::ClassMethods
4
+ Interest = Class.new(Instance)
5
+
6
+ class Interests < Collection
7
+ PATH_KEY = DATA_KEY = 'interests'
8
+ CHILD_CLASS = Interest
7
9
  end
8
10
  end
9
11
  end
@@ -1,16 +1,14 @@
1
- require 'mailchimp_api_v3/interests'
2
-
3
1
  module Mailchimp
4
2
  class List
5
- class InterestCategory
6
- #- VALID_TYPES = %w(checkboxes dropdown radio hidden)
7
-
8
- include Instance::InstanceMethods
9
- extend Instance::ClassMethods
3
+ class InterestCategory < Instance
4
+ require 'mailchimp_api_v3/interest_category/subclasses'
5
+ include Subclasses
6
+ end
10
7
 
11
- def interests(options = {})
12
- subclass_from Interests, options
13
- end
8
+ class InterestCategories < Collection
9
+ PATH_KEY = 'interest-categories'
10
+ DATA_KEY = 'categories'
11
+ CHILD_CLASS = InterestCategory
14
12
  end
15
13
  end
16
14
  end
@@ -0,0 +1,14 @@
1
+ require 'mailchimp_api_v3/interest'
2
+
3
+ module Mailchimp
4
+ class List
5
+ class InterestCategory
6
+ module Subclasses
7
+ #- VALID_TYPES = %w(checkboxes dropdown radio hidden)
8
+ def interests(options = {})
9
+ subclass_from Interests, options
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,26 +1,15 @@
1
- require 'mailchimp_api_v3/members'
2
- require 'mailchimp_api_v3/interest_categories'
3
-
4
1
  module Mailchimp
5
- class List
6
- include Instance::InstanceMethods
7
- extend Instance::ClassMethods
8
-
9
- def members(options = {})
10
- # Turn an email into an id
11
- if options.is_a?(String) && (options =~ /\A[^@]+@[^@]+\z/)
12
- options = OpenSSL::Digest.digest('MD5', options).unpack('H*').first
13
- end
14
-
15
- subclass_from Members, options
16
- end
17
-
18
- def interest_categories(options = {})
19
- subclass_from InterestCategories, options
20
- end
2
+ class List < Instance
3
+ require 'mailchimp_api_v3/list/subclasses'
4
+ include Subclasses
21
5
 
22
6
  def id_and_name
23
7
  "#{id}___#{name}"
24
8
  end
25
9
  end
10
+
11
+ class Lists < Collection
12
+ PATH_KEY = DATA_KEY = 'lists'
13
+ CHILD_CLASS = List
14
+ end
26
15
  end
@@ -0,0 +1,21 @@
1
+ require 'mailchimp_api_v3/member'
2
+ require 'mailchimp_api_v3/interest_category'
3
+
4
+ module Mailchimp
5
+ class List
6
+ module Subclasses
7
+ def members(options = {})
8
+ # Turn an email into an id
9
+ if options.is_a?(String) && (options =~ /\A[^@]+@[^@]+\z/)
10
+ options = OpenSSL::Digest.digest('MD5', options).unpack('H*').first
11
+ end
12
+
13
+ subclass_from Members, options
14
+ end
15
+
16
+ def interest_categories(options = {})
17
+ subclass_from InterestCategories, options
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,9 +1,6 @@
1
1
  module Mailchimp
2
2
  class List
3
- class Member
4
- include Instance::InstanceMethods
5
- extend Instance::ClassMethods
6
-
3
+ class Member < Instance
7
4
  def first_name
8
5
  @first_name ||= merge_fields['FNAME']
9
6
  end
@@ -51,5 +48,10 @@ module Mailchimp
51
48
  ]
52
49
  end
53
50
  end
51
+
52
+ class Members < Collection
53
+ PATH_KEY = DATA_KEY = 'members'
54
+ CHILD_CLASS = Member
55
+ end
54
56
  end
55
57
  end
@@ -1,3 +1,3 @@
1
1
  module Mailchimp
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
@@ -3,18 +3,18 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'mailchimp_api_v3/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = 'mailchimp_api_v3'
7
- spec.version = Mailchimp::VERSION
8
- spec.authors = ['Xenapto']
9
- spec.email = ['developers@xenapto.com']
10
- spec.description = 'A simple gem to interact with Mailchimp through their API v3'
11
- spec.summary = 'Example: mailchimp.lists("My first list").member("ann@example.com")'
12
- spec.homepage = 'https://github.com/Xenapto/mailchimp_api_v3'
13
- spec.license = 'BSD'
6
+ spec.name = 'mailchimp_api_v3'
7
+ spec.version = Mailchimp::VERSION
8
+ spec.authors = ['Xenapto']
9
+ spec.email = ['developers@xenapto.com']
10
+ spec.description = 'A simple gem to interact with Mailchimp through their API v3'
11
+ spec.summary = 'Example: mailchimp.lists("My first list").member("ann@example.com")'
12
+ spec.homepage = 'https://github.com/Xenapto/mailchimp_api_v3'
13
+ spec.license = 'BSD'
14
14
 
15
- spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
- spec.executables = spec.files.grep(%r{^bin\/}) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features|coverage)\/})
15
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
16
+ spec.executables = spec.files.grep(%r{^bin\/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features|coverage)\/})
18
18
  spec.require_paths = ['lib']
19
19
 
20
20
  spec.add_runtime_dependency 'rest-client', '~> 1.6', '> 1.6'
@@ -35,22 +35,35 @@ describe Mailchimp::Client, vcr: { cassette_name: 'mailchimp' } do
35
35
  end
36
36
  end
37
37
 
38
- context 'problems we can retry the request for' do
38
+ context 'exceptions' do
39
39
  let(:client) { Mailchimp::Client.new }
40
40
 
41
- it 'eventually raises the exception' do
42
- allow(client).to receive(:remote_no_payload).and_raise SocketError.new('test message')
41
+ context 'problems we can retry the request for' do
42
+ it 'eventually raises the exception' do
43
+ allow(client).to receive(:remote_no_payload).and_raise SocketError.new('test message')
43
44
 
44
- expect { client.account }.to raise_error { |e|
45
- expect(e).to be_an(SocketError)
46
- expect(e.message).to eq('test message')
47
- }
45
+ expect { client.account }.to raise_error { |e|
46
+ expect(e).to be_a(SocketError)
47
+ expect(e.message).to eq('test message')
48
+ }
49
+ end
50
+
51
+ it 'only raises the exception after several retries' do
52
+ allow(client).to receive(:remote_no_payload).twice.and_raise SocketError.new('test message')
53
+ allow(client).to receive(:remote_no_payload).and_return '"id":1'
54
+ expect { client.account }.not_to raise_error
55
+ end
48
56
  end
49
57
 
50
- it 'only raises the exception after several retries' do
51
- allow(client).to receive(:remote_no_payload).twice.and_raise SocketError.new('test message')
52
- allow(client).to receive(:remote_no_payload).and_return '"id":1'
53
- expect { client.account }.not_to raise_error
58
+ context 'unexpected error' do
59
+ it 'raises an exception if it encounters an unexpected error' do
60
+ exception = NotImplementedError.new('test message')
61
+
62
+ expect { client.__send__(:managed_remote_exception, exception) }.to raise_error { |e|
63
+ expect(e).to be_a(NotImplementedError)
64
+ expect(e.message).to eq('test message')
65
+ }
66
+ end
54
67
  end
55
68
  end
56
69
  end
data/spec/spec_helper.rb CHANGED
@@ -7,7 +7,7 @@ unless ENV['NO_SIMPLECOV']
7
7
  SimpleCov.coverage_dir(dir)
8
8
  end
9
9
 
10
- SimpleCov.start
10
+ SimpleCov.start { add_filter '/spec/' }
11
11
  Coveralls.wear! if ENV['COVERALLS_REPO_TOKEN']
12
12
  end
13
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailchimp_api_v3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xenapto
@@ -230,13 +230,11 @@ files:
230
230
  - lib/mailchimp_api_v3/exception.rb
231
231
  - lib/mailchimp_api_v3/instance.rb
232
232
  - lib/mailchimp_api_v3/interest.rb
233
- - lib/mailchimp_api_v3/interest_categories.rb
234
233
  - lib/mailchimp_api_v3/interest_category.rb
235
- - lib/mailchimp_api_v3/interests.rb
234
+ - lib/mailchimp_api_v3/interest_category/subclasses.rb
236
235
  - lib/mailchimp_api_v3/list.rb
237
- - lib/mailchimp_api_v3/lists.rb
236
+ - lib/mailchimp_api_v3/list/subclasses.rb
238
237
  - lib/mailchimp_api_v3/member.rb
239
- - lib/mailchimp_api_v3/members.rb
240
238
  - lib/mailchimp_api_v3/version.rb
241
239
  - mailchimp_api_v3.gemspec
242
240
  - spec/fixtures/cassettes/mailchimp.yml
@@ -1,23 +0,0 @@
1
- require 'mailchimp_api_v3/interest_category'
2
-
3
- module Mailchimp
4
- class List
5
- class InterestCategories < Array
6
- include Collection
7
-
8
- class << self
9
- def path_key
10
- 'interest-categories'
11
- end
12
-
13
- def data_key
14
- 'categories'
15
- end
16
-
17
- def child_class
18
- InterestCategory
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,25 +0,0 @@
1
- require 'mailchimp_api_v3/interest'
2
-
3
- module Mailchimp
4
- class List
5
- class InterestCategory
6
- class Interests < Array
7
- include Collection
8
-
9
- class << self
10
- def path_key
11
- 'interests'
12
- end
13
-
14
- def data_key
15
- 'interests'
16
- end
17
-
18
- def child_class
19
- Interest
20
- end
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,21 +0,0 @@
1
- require 'mailchimp_api_v3/list'
2
-
3
- module Mailchimp
4
- class Lists < Array
5
- include Collection
6
-
7
- class << self
8
- def path_key
9
- 'lists'
10
- end
11
-
12
- def data_key
13
- 'lists'
14
- end
15
-
16
- def child_class
17
- List
18
- end
19
- end
20
- end
21
- end
@@ -1,23 +0,0 @@
1
- require 'mailchimp_api_v3/member'
2
-
3
- module Mailchimp
4
- class List
5
- class Members < Array
6
- include Collection
7
-
8
- class << self
9
- def path_key
10
- 'members'
11
- end
12
-
13
- def data_key
14
- 'members'
15
- end
16
-
17
- def child_class
18
- Member
19
- end
20
- end
21
- end
22
- end
23
- end