mlb 0.6.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +2 -0
- data/LICENSE.txt +21 -0
- data/README.md +115 -98
- data/bin/console +10 -0
- data/bin/setup +6 -0
- data/lib/mlb/client.rb +73 -0
- data/lib/mlb/connection.rb +80 -0
- data/lib/mlb/errors/bad_gateway.rb +5 -0
- data/lib/mlb/errors/bad_request.rb +5 -0
- data/lib/mlb/errors/client_error.rb +5 -0
- data/lib/mlb/errors/connection_exception.rb +5 -0
- data/lib/mlb/errors/error.rb +3 -0
- data/lib/mlb/errors/forbidden.rb +5 -0
- data/lib/mlb/errors/gateway_timeout.rb +5 -0
- data/lib/mlb/errors/gone.rb +5 -0
- data/lib/mlb/errors/http_error.rb +14 -0
- data/lib/mlb/errors/internal_server_error.rb +5 -0
- data/lib/mlb/errors/network_error.rb +5 -0
- data/lib/mlb/errors/not_acceptable.rb +5 -0
- data/lib/mlb/errors/not_found.rb +5 -0
- data/lib/mlb/errors/payload_too_large.rb +5 -0
- data/lib/mlb/errors/server_error.rb +5 -0
- data/lib/mlb/errors/service_unavailable.rb +5 -0
- data/lib/mlb/errors/too_many_redirects.rb +5 -0
- data/lib/mlb/errors/too_many_requests.rb +5 -0
- data/lib/mlb/errors/unauthorized.rb +5 -0
- data/lib/mlb/errors/unprocessable_entity.rb +5 -0
- data/lib/mlb/player.rb +17 -22
- data/lib/mlb/redirect_handler.rb +55 -0
- data/lib/mlb/request_builder.rb +48 -0
- data/lib/mlb/response_parser.rb +61 -0
- data/lib/mlb/team.rb +33 -134
- data/lib/mlb/transaction.rb +37 -0
- data/lib/mlb/version.rb +3 -1
- data/lib/mlb.rb +3 -3
- data/sig/mlb.rbs +191 -0
- metadata +59 -119
- data/.yardopts +0 -5
- data/CONTRIBUTING.md +0 -49
- data/LICENSE.md +0 -20
- data/Rakefile +0 -22
- data/lib/mlb/request.rb +0 -24
- data/lib/mlb/response/parse_json.rb +0 -25
- data/mlb.gemspec +0 -26
- data/spec/helper.rb +0 -24
- data/spec/mlb_spec.rb +0 -53
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e82207f5345873c47ef01b18d32ed5dc131a7a2a2531b5c5adf2ca87e2c5d397
|
4
|
+
data.tar.gz: 597c40742c137216cc3210362b9a157dc28ef25cd5dacff689489821323cb804
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c9e096ebd1e2a1d88d618507c8e3d15b540f06c146b29c3dff1abe2dbf581521858fbf1b6362ad251c241db89330f3d2c4d6fb94753d8236056b5ec2910bfb69
|
7
|
+
data.tar.gz: e962f38e4fc333cafb5618ab1c5bdf66e53aed74b12a2e8be708877a2a8100af96410bfd8e196ce51ad4570490da98c4ade2eaefee845c9cf9230dacb2a7f5a2
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020-2024 Erik Berlin, Nilesh Trivedi
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,104 +1,121 @@
|
|
1
|
-
|
2
|
-
[![
|
3
|
-
[![
|
4
|
-
[![
|
1
|
+
[![Tests](https://github.com/sferik/mlb-ruby/actions/workflows/test.yml/badge.svg)](https://github.com/sferik/mlb-ruby/actions/workflows/test.yml)
|
2
|
+
[![Linter](https://github.com/sferik/mlb-ruby/actions/workflows/lint.yml/badge.svg)](https://github.com/sferik/mlb-ruby/actions/workflows/lint.yml)
|
3
|
+
[![Mutant](https://github.com/sferik/mlb-ruby/actions/workflows/mutant.yml/badge.svg)](https://github.com/sferik/mlb-ruby/actions/workflows/mutant.yml)
|
4
|
+
[![Typer Checker](https://github.com/sferik/mlb-ruby/actions/workflows/steep.yml/badge.svg)](https://github.com/sferik/mlb-ruby/actions/workflows/steep.yml)
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/mlb.svg)](https://rubygems.org/gems/mlb)
|
5
6
|
|
6
|
-
[
|
7
|
-
[travis]: http://travis-ci.org/sferik/mlb
|
8
|
-
[gemnasium]: https://gemnasium.com/sferik/mlb
|
7
|
+
# A [Ruby](https://www.ruby-lang.org) interface to the [MLB Data API](https://appac.github.io/mlb-data-api-docs/)
|
9
8
|
|
10
|
-
|
9
|
+
## Follow
|
10
|
+
|
11
|
+
For updates and announcements, follow [@sferik](https://x.com/sferik) on X.
|
11
12
|
|
12
13
|
## Installation
|
14
|
+
|
15
|
+
Install the gem and add to the application's Gemfile:
|
16
|
+
|
17
|
+
bundle add mlb
|
18
|
+
|
19
|
+
Or, if Bundler is not being used to manage dependencies:
|
20
|
+
|
13
21
|
gem install mlb
|
14
22
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
[
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
[
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require "mlb"
|
27
|
+
|
28
|
+
dbacks = MLB::Team.all(season: 2024).first
|
29
|
+
dbacks.name_display_full # => "Arizona Diamondbacks"
|
30
|
+
dbacks.name_display_brief # => "D-backs"
|
31
|
+
dbacks.name_abbrev # => "AZ"
|
32
|
+
dbacks.city # => "Phoenix"
|
33
|
+
dbacks.league_full # => "National League"
|
34
|
+
dbacks.league_abbrev # => "NL"
|
35
|
+
dbacks.spring_league_full # => "Cactus League"
|
36
|
+
dbacks.spring_league_abbrev # => "CL"
|
37
|
+
dbacks.division_full # => "National League West"
|
38
|
+
dbacks.division_abbrev # => "NLW"
|
39
|
+
dbacks.first_year_of_play # => "1996"
|
40
|
+
dbacks.venue_name # => "Chase Field"
|
41
|
+
|
42
|
+
blaze = dbacks.roster.first
|
43
|
+
blaze.name_display_first_last # => "Blaze Alexander"
|
44
|
+
blaze.jersey_number # => "9"
|
45
|
+
blaze.primary_position # => "6"
|
46
|
+
blaze.position_txt # => "SS"
|
47
|
+
blaze.height_feet # => "5"
|
48
|
+
blaze.height_inches # => "11"
|
49
|
+
blaze.weight # => "160"
|
50
|
+
blaze.bats # => "R"
|
51
|
+
blaze.throws # => "R"
|
52
|
+
blaze.birth_date # => "1999-06-11T00:00:00"
|
53
|
+
blaze.start_date # => "2022-11-15T00:00:00"
|
54
|
+
blaze.pro_debut_date # => "2024-03-28T00:00:00"
|
55
|
+
```
|
56
|
+
|
57
|
+
## Sponsorship
|
58
|
+
|
59
|
+
By contributing to the project, you help:
|
60
|
+
|
61
|
+
1. Maintain the library: Keeping it up-to-date and secure.
|
62
|
+
2. Add new features: Enhancements that make your life easier.
|
63
|
+
3. Provide support: Faster responses to issues and feature requests.
|
64
|
+
|
65
|
+
⭐️ Bonus: Sponsors will get priority support and influence over the project roadmap. We will also list your name or your company's logo on our GitHub page.
|
66
|
+
|
67
|
+
Building and maintaining an open-source project like this takes a considerable amount of time and effort. Your sponsorship can help sustain this project. Even a small monthly donation makes a huge difference!
|
68
|
+
|
69
|
+
[Click here to sponsor this project.](https://github.com/sponsors/sferik)
|
70
|
+
|
71
|
+
## Development
|
72
|
+
|
73
|
+
1. Checkout and repo:
|
74
|
+
|
75
|
+
git checkout git@github.com:sferik/mlb-ruby.git
|
76
|
+
|
77
|
+
2. Enter the repo’s directory:
|
78
|
+
|
79
|
+
cd mlb-ruby
|
80
|
+
|
81
|
+
3. Install dependencies via Bundler:
|
82
|
+
|
83
|
+
bin/setup
|
84
|
+
|
85
|
+
4. Run the default Rake task to ensure all tests pass:
|
86
|
+
|
87
|
+
bundle exec rake
|
88
|
+
|
89
|
+
5. Create a new branch for your feature or bug fix:
|
90
|
+
|
91
|
+
git checkout -b my-new-branch
|
92
|
+
|
93
|
+
## Contributing
|
94
|
+
|
95
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/sferik/mlb-ruby.
|
96
|
+
|
97
|
+
Pull requests will only be accepted if they meet all the following criteria:
|
98
|
+
|
99
|
+
1. Code must conform to [Standard Ruby](https://github.com/standardrb/standard#readme). This can be verified with:
|
100
|
+
|
101
|
+
bundle exec rake standard
|
102
|
+
|
103
|
+
2. Code must conform to the [RuboCop rules](https://github.com/rubocop/rubocop#readme). This can be verified with:
|
104
|
+
|
105
|
+
bundle exec rake rubocop
|
106
|
+
|
107
|
+
3. 100% C0 code coverage. This can be verified with:
|
108
|
+
|
109
|
+
bundle exec rake test
|
110
|
+
|
111
|
+
4. 100% mutation coverage. This can be verified with:
|
112
|
+
|
113
|
+
bundle exec rake mutant
|
114
|
+
|
115
|
+
5. RBS type signatures (in `sig/mlb.rbs`). This can be verified with:
|
116
|
+
|
117
|
+
bundle exec rake steep
|
118
|
+
|
119
|
+
## License
|
120
|
+
|
121
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/bin/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "mlb"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
require "irb"
|
10
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/mlb/client.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
require_relative "connection"
|
3
|
+
require_relative "redirect_handler"
|
4
|
+
require_relative "request_builder"
|
5
|
+
require_relative "response_parser"
|
6
|
+
|
7
|
+
module MLB
|
8
|
+
class Client
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
DEFAULT_BASE_URL = "https://lookup-service-prod.mlb.com/json/".freeze
|
12
|
+
DEFAULT_ARRAY_CLASS = Array
|
13
|
+
DEFAULT_OBJECT_CLASS = Hash
|
14
|
+
|
15
|
+
attr_accessor :base_url, :default_array_class, :default_object_class
|
16
|
+
|
17
|
+
def_delegators :@connection, :open_timeout, :read_timeout, :write_timeout, :proxy_url, :debug_output
|
18
|
+
def_delegators :@connection, :open_timeout=, :read_timeout=, :write_timeout=, :proxy_url=, :debug_output=
|
19
|
+
def_delegators :@redirect_handler, :max_redirects
|
20
|
+
def_delegators :@redirect_handler, :max_redirects=
|
21
|
+
|
22
|
+
def initialize(base_url: DEFAULT_BASE_URL,
|
23
|
+
open_timeout: Connection::DEFAULT_OPEN_TIMEOUT,
|
24
|
+
read_timeout: Connection::DEFAULT_READ_TIMEOUT,
|
25
|
+
write_timeout: Connection::DEFAULT_WRITE_TIMEOUT,
|
26
|
+
debug_output: Connection::DEFAULT_DEBUG_OUTPUT,
|
27
|
+
proxy_url: nil,
|
28
|
+
default_array_class: DEFAULT_ARRAY_CLASS,
|
29
|
+
default_object_class: DEFAULT_OBJECT_CLASS,
|
30
|
+
max_redirects: RedirectHandler::DEFAULT_MAX_REDIRECTS)
|
31
|
+
|
32
|
+
@base_url = base_url
|
33
|
+
initialize_default_classes(default_array_class, default_object_class)
|
34
|
+
@connection = Connection.new(open_timeout:, read_timeout:, write_timeout:, debug_output:, proxy_url:)
|
35
|
+
@request_builder = RequestBuilder.new
|
36
|
+
@redirect_handler = RedirectHandler.new(connection: @connection, request_builder: @request_builder, max_redirects:)
|
37
|
+
@response_parser = ResponseParser.new
|
38
|
+
end
|
39
|
+
|
40
|
+
def get(endpoint, headers: {}, array_class: default_array_class, object_class: default_object_class)
|
41
|
+
execute_request(:get, endpoint, headers:, array_class:, object_class:)
|
42
|
+
end
|
43
|
+
|
44
|
+
def post(endpoint, body = nil, headers: {}, array_class: default_array_class, object_class: default_object_class)
|
45
|
+
execute_request(:post, endpoint, body:, headers:, array_class:, object_class:)
|
46
|
+
end
|
47
|
+
|
48
|
+
def put(endpoint, body = nil, headers: {}, array_class: default_array_class, object_class: default_object_class)
|
49
|
+
execute_request(:put, endpoint, body:, headers:, array_class:, object_class:)
|
50
|
+
end
|
51
|
+
|
52
|
+
def delete(endpoint, headers: {}, array_class: default_array_class, object_class: default_object_class)
|
53
|
+
execute_request(:delete, endpoint, headers:, array_class:, object_class:)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def initialize_default_classes(default_array_class, default_object_class)
|
59
|
+
@default_array_class = default_array_class
|
60
|
+
@default_object_class = default_object_class
|
61
|
+
end
|
62
|
+
|
63
|
+
def execute_request(http_method, endpoint, body: nil, headers: {}, array_class: default_array_class, object_class: default_object_class)
|
64
|
+
uri = URI.join(base_url, endpoint)
|
65
|
+
request = @request_builder.build(http_method:, uri:, body:, headers:)
|
66
|
+
response = @connection.perform(request:)
|
67
|
+
response = @redirect_handler.handle(response:, request:, base_url:)
|
68
|
+
@response_parser.parse(response:, array_class:, object_class:)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
CLIENT = Client.new
|
73
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
require "net/http"
|
3
|
+
require "openssl"
|
4
|
+
require "uri"
|
5
|
+
require_relative "errors/network_error"
|
6
|
+
|
7
|
+
module MLB
|
8
|
+
class Connection
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
DEFAULT_HOST = "lookup-service-prod.mlb.com".freeze
|
12
|
+
DEFAULT_PORT = 443
|
13
|
+
DEFAULT_OPEN_TIMEOUT = 60 # seconds
|
14
|
+
DEFAULT_READ_TIMEOUT = 60 # seconds
|
15
|
+
DEFAULT_WRITE_TIMEOUT = 60 # seconds
|
16
|
+
DEFAULT_DEBUG_OUTPUT = File.open(File::NULL, "w")
|
17
|
+
NETWORK_ERRORS = [
|
18
|
+
Errno::ECONNREFUSED,
|
19
|
+
Errno::ECONNRESET,
|
20
|
+
Net::OpenTimeout,
|
21
|
+
Net::ReadTimeout,
|
22
|
+
OpenSSL::SSL::SSLError
|
23
|
+
].freeze
|
24
|
+
|
25
|
+
attr_accessor :open_timeout, :read_timeout, :write_timeout, :debug_output
|
26
|
+
attr_reader :proxy_url, :proxy_uri
|
27
|
+
|
28
|
+
def_delegator :proxy_uri, :host, :proxy_host
|
29
|
+
def_delegator :proxy_uri, :port, :proxy_port
|
30
|
+
def_delegator :proxy_uri, :user, :proxy_user
|
31
|
+
def_delegator :proxy_uri, :password, :proxy_pass
|
32
|
+
|
33
|
+
def initialize(open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT,
|
34
|
+
write_timeout: DEFAULT_WRITE_TIMEOUT, debug_output: DEFAULT_DEBUG_OUTPUT, proxy_url: nil)
|
35
|
+
@open_timeout = open_timeout
|
36
|
+
@read_timeout = read_timeout
|
37
|
+
@write_timeout = write_timeout
|
38
|
+
@debug_output = debug_output
|
39
|
+
self.proxy_url = proxy_url unless proxy_url.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def perform(request:)
|
43
|
+
host = request.uri.host || DEFAULT_HOST
|
44
|
+
port = request.uri.port || DEFAULT_PORT
|
45
|
+
http_client = build_http_client(host, port)
|
46
|
+
http_client.use_ssl = request.uri.scheme.eql?("https")
|
47
|
+
http_client.request(request)
|
48
|
+
rescue *NETWORK_ERRORS => e
|
49
|
+
raise NetworkError, "Network error: #{e}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def proxy_url=(proxy_url)
|
53
|
+
@proxy_url = proxy_url
|
54
|
+
proxy_uri = URI(proxy_url)
|
55
|
+
raise ArgumentError, "Invalid proxy URL: #{proxy_uri}" unless proxy_uri.is_a?(URI::HTTP)
|
56
|
+
|
57
|
+
@proxy_uri = proxy_uri
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def build_http_client(host = DEFAULT_HOST, port = DEFAULT_PORT)
|
63
|
+
http_client = if proxy_uri
|
64
|
+
Net::HTTP.new(host, port, proxy_host, proxy_port, proxy_user, proxy_pass)
|
65
|
+
else
|
66
|
+
Net::HTTP.new(host, port)
|
67
|
+
end
|
68
|
+
configure_http_client(http_client)
|
69
|
+
end
|
70
|
+
|
71
|
+
def configure_http_client(http_client)
|
72
|
+
http_client.tap do |c|
|
73
|
+
c.open_timeout = open_timeout
|
74
|
+
c.read_timeout = read_timeout
|
75
|
+
c.write_timeout = write_timeout
|
76
|
+
c.set_debug_output(debug_output)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/mlb/player.rb
CHANGED
@@ -1,26 +1,21 @@
|
|
1
1
|
module MLB
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
Player = Struct.new(:bats, :birth_date, :college, :end_date, :height_feet,
|
3
|
+
:height_inches, :jersey_number, :name_display_first_last,
|
4
|
+
:name_display_last_first, :name_first, :name_full, :name_last, :name_use,
|
5
|
+
:player_id, :position_txt, :primary_position, :pro_debut_date, :start_date,
|
6
|
+
:starter_sw, :status_code, :team_abbrev, :team_code, :team_id, :team_name,
|
7
|
+
:throws, :weight, keyword_init: true) do
|
8
|
+
def team
|
9
|
+
require_relative "team"
|
10
|
+
sport_code = "'mlb'"
|
11
|
+
season = Time.now.year
|
12
|
+
all_star_sw = "'N'"
|
13
|
+
params = {sport_code:, season:, all_star_sw:}
|
14
|
+
query_string = URI.encode_www_form(params)
|
15
|
+
response = CLIENT.get("named.team_all_season.bam?#{query_string}")
|
16
|
+
teams = response[:team_all_season][:queryResults][:row]
|
17
|
+
team = teams.find { |t| t[:team_id] == team_id.to_s }
|
18
|
+
Team.new(**team)
|
12
19
|
end
|
13
|
-
|
14
|
-
# Returns an array of Player objects given a team roster
|
15
|
-
def self.all_from_roster(players)
|
16
|
-
players.map do |player|
|
17
|
-
new(
|
18
|
-
:name => player['player'],
|
19
|
-
:number => player['number'],
|
20
|
-
:position => player['position']
|
21
|
-
)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
20
|
end
|
26
21
|
end
|