cybercoach 0.2.0 → 0.3.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 +4 -4
- data/.gitignore +45 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +23 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/cybercoach.gemspec +27 -0
- data/lib/cybercoach/abstract_resource.rb +162 -0
- data/lib/cybercoach/entry.rb +166 -0
- data/lib/cybercoach/format_not_supported_error.rb +7 -0
- data/lib/cybercoach/http_error.rb +27 -0
- data/lib/cybercoach/pageable.rb +38 -0
- data/lib/cybercoach/partnership.rb +151 -0
- data/lib/cybercoach/post_createable.rb +49 -0
- data/lib/cybercoach/privacy_level.rb +21 -0
- data/lib/cybercoach/put_createable.rb +48 -0
- data/lib/cybercoach/resource.rb +94 -0
- data/lib/cybercoach/resource_page.rb +191 -0
- data/lib/cybercoach/settings.rb +16 -0
- data/lib/cybercoach/sport.rb +104 -0
- data/lib/cybercoach/subclass_responsibility_error.rb +7 -0
- data/lib/cybercoach/subscription.rb +145 -0
- data/lib/cybercoach/user.rb +159 -0
- data/lib/cybercoach/version.rb +10 -0
- data/lib/cybercoach.rb +19 -0
- data/spec/lib/cybercoach/entry_spec.rb +95 -0
- data/spec/lib/cybercoach/partnership_spec.rb +79 -0
- data/spec/lib/cybercoach/privacy_level_spec.rb +15 -0
- data/spec/lib/cybercoach/resource_helper.rb +11 -0
- data/spec/lib/cybercoach/resource_page_spec.rb +44 -0
- data/spec/lib/cybercoach/settings_spec.rb +10 -0
- data/spec/lib/cybercoach/sport_spec.rb +29 -0
- data/spec/lib/cybercoach/subscription_spec.rb +129 -0
- data/spec/lib/cybercoach/user_helper.rb +22 -0
- data/spec/lib/cybercoach/user_spec.rb +82 -0
- data/spec/lib/cybercoach_helper.rb +2 -0
- data/spec/lib/integration_spec.rb +56 -0
- data/spec/spec_helper.rb +19 -0
- metadata +56 -4
@@ -0,0 +1,151 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# A Partnership consists of two Users, which participate in different Sport
|
4
|
+
# with Subscriptions, to which Entries are submitted.
|
5
|
+
#
|
6
|
+
class Partnership < Resource
|
7
|
+
#
|
8
|
+
# It is pageable.
|
9
|
+
#
|
10
|
+
include Pageable
|
11
|
+
|
12
|
+
#
|
13
|
+
# It is creatable by PUT.
|
14
|
+
#
|
15
|
+
include PutCreateable
|
16
|
+
|
17
|
+
#
|
18
|
+
# :attr: proposer
|
19
|
+
# The User who proposed it.
|
20
|
+
#
|
21
|
+
|
22
|
+
#
|
23
|
+
# :attr: proposed
|
24
|
+
# The User it is proposed to.
|
25
|
+
#
|
26
|
+
|
27
|
+
#
|
28
|
+
# :attr: subscriptions
|
29
|
+
# The Subscriptions.
|
30
|
+
#
|
31
|
+
|
32
|
+
#
|
33
|
+
# :attr: confirmed_by_proposer
|
34
|
+
# True if the proposing User has confirmed it, false otherwise.
|
35
|
+
#
|
36
|
+
|
37
|
+
#
|
38
|
+
# :attr: confirmed_by_proposed
|
39
|
+
# True if the proposed User has confirmed it, false otherwise.
|
40
|
+
#
|
41
|
+
|
42
|
+
#
|
43
|
+
# :attr: privacy_level
|
44
|
+
# The privacy level, see PrivacyLevel constants.
|
45
|
+
#
|
46
|
+
|
47
|
+
attr_accessor :proposer,
|
48
|
+
:proposed,
|
49
|
+
:subscriptions,
|
50
|
+
:confirmed_by_proposer,
|
51
|
+
:confirmed_by_proposed,
|
52
|
+
:privacy_level
|
53
|
+
|
54
|
+
#
|
55
|
+
# :category: Serialization
|
56
|
+
#
|
57
|
+
# Creates itself from a serializable representation, which only contains
|
58
|
+
# simple data types.
|
59
|
+
# serializable:: A hash with the keys:
|
60
|
+
# * uri:: The URI.
|
61
|
+
# * id:: The identifier.
|
62
|
+
# * user1:: A User serializable of the proposer.
|
63
|
+
# * user2:: A User serializable of the proposed.
|
64
|
+
# * subscriptions:: Subscription serializables.
|
65
|
+
# * userconfirmed1:: True if the proposing User has confirmed it, false otherwise.
|
66
|
+
# * userconfirmed2:: True if the proposed User has confirmed it, false otherwise.
|
67
|
+
# * publicvisible:: The privacy level, see PrivacyLevel constants.
|
68
|
+
#
|
69
|
+
def from_serializable(serializable)
|
70
|
+
super(serializable)
|
71
|
+
@proposer = nil
|
72
|
+
unless serializable['user1'].nil?
|
73
|
+
@proposer = User.new
|
74
|
+
@proposer.from_serializable(serializable['user1'])
|
75
|
+
end
|
76
|
+
@proposed = nil
|
77
|
+
unless serializable['user2'].nil?
|
78
|
+
@proposed = User.new
|
79
|
+
@proposed.from_serializable(serializable['user2'])
|
80
|
+
end
|
81
|
+
@subscriptions = []
|
82
|
+
unless serializable['subscriptions'].nil?
|
83
|
+
@subscriptions = serializable['subscriptions'].map do
|
84
|
+
|subscription_serializable|
|
85
|
+
subscription = Subscription.new
|
86
|
+
subscription.from_serializable(subscription_serializable)
|
87
|
+
subscription
|
88
|
+
end
|
89
|
+
end
|
90
|
+
@confirmed_by_proposer = serializable['userconfirmed1']
|
91
|
+
@confirmed_by_proposed = serializable['userconfirmed2']
|
92
|
+
@privacy_level = serializable['publicvisible']
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# :category: Serialization
|
97
|
+
#
|
98
|
+
# Returns a serializable representation, which only contains simple data
|
99
|
+
# types.
|
100
|
+
# The hash has the keys:
|
101
|
+
# * uri:: The URI.
|
102
|
+
# * id:: The identifier.
|
103
|
+
# * user1:: A User serializable of the proposer.
|
104
|
+
# * user2:: A User serializable of the proposed.
|
105
|
+
# * publicvisible:: The privacy level, see PrivacyLevel constants.
|
106
|
+
#
|
107
|
+
def to_serializable
|
108
|
+
serializable = super
|
109
|
+
unless @proposer.nil?
|
110
|
+
serializable['user1'] = @proposer.to_serializable
|
111
|
+
end
|
112
|
+
unless @proposed.nil?
|
113
|
+
serializable['user2'] = @proposed.to_serializable
|
114
|
+
end
|
115
|
+
serializable['publicvisible'] = @privacy_level
|
116
|
+
serializable
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# :category: Configuration
|
121
|
+
#
|
122
|
+
# Returns 'partnership'.
|
123
|
+
#
|
124
|
+
def singular_name
|
125
|
+
'partnership'
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# :category: Configuration
|
130
|
+
#
|
131
|
+
# Returns 'partnerships'.
|
132
|
+
#
|
133
|
+
def plural_name
|
134
|
+
'partnerships'
|
135
|
+
end
|
136
|
+
|
137
|
+
protected
|
138
|
+
|
139
|
+
#
|
140
|
+
# :category: Invalidation
|
141
|
+
#
|
142
|
+
# Sets the uri to the base uri and the proposer's and proposed's username if
|
143
|
+
# neither of them is nil.
|
144
|
+
#
|
145
|
+
def invalidate_uri
|
146
|
+
unless @proposer.nil? || @proposed.nil?
|
147
|
+
@uri = "#{resource_base_uri}#{@proposer.username};#{@proposed.username}/"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# Mixin for a resource that gets its URI assigned from the server.
|
4
|
+
# Include it in a class to use it.
|
5
|
+
#
|
6
|
+
module PostCreateable
|
7
|
+
#
|
8
|
+
# Installs class and instance methods in the class it is included in.
|
9
|
+
#
|
10
|
+
def self.included(base)
|
11
|
+
base.extend ClassMethods
|
12
|
+
base.send :include, InstanceMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# The class methods to install.
|
17
|
+
#
|
18
|
+
module ClassMethods
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# The instance methods to install.
|
23
|
+
#
|
24
|
+
module InstanceMethods
|
25
|
+
#
|
26
|
+
# :category: CRUD
|
27
|
+
#
|
28
|
+
# Creates it.
|
29
|
+
# Gets the URI from the response and reads itself again.
|
30
|
+
# Raises HttpError if the request is unsuccessful.
|
31
|
+
# options:: A hash of options to send with the request.
|
32
|
+
#
|
33
|
+
def create(options = {})
|
34
|
+
invalidate_uri
|
35
|
+
invalidate_options
|
36
|
+
options = @options.merge(options).merge(
|
37
|
+
body: serialize
|
38
|
+
)
|
39
|
+
response = self.class.post(resource_base_uri, options)
|
40
|
+
if response.success?
|
41
|
+
@uri = response.headers['location']
|
42
|
+
read(options)
|
43
|
+
else
|
44
|
+
raise HttpError.new(response.response)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# The CyberCoach privacy levels.
|
4
|
+
#
|
5
|
+
module PrivacyLevel
|
6
|
+
#
|
7
|
+
# Only the owner of the resource can access its properties.
|
8
|
+
#
|
9
|
+
OWNER = 0
|
10
|
+
|
11
|
+
#
|
12
|
+
# Only registered users can access the resource's properties.
|
13
|
+
#
|
14
|
+
REGISTERED_USER = 1
|
15
|
+
|
16
|
+
#
|
17
|
+
# Everybody can access the resource's properties.
|
18
|
+
#
|
19
|
+
EVERYBODY = 2
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# Mixin for a resource that gets its URI assigned from the client.
|
4
|
+
# Include it in a class to use it.
|
5
|
+
#
|
6
|
+
module PutCreateable
|
7
|
+
#
|
8
|
+
# Installs class and instance methods in the class it is included in.
|
9
|
+
#
|
10
|
+
def self.included(base)
|
11
|
+
base.extend ClassMethods
|
12
|
+
base.send :include, InstanceMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# The class methods to install.
|
17
|
+
#
|
18
|
+
module ClassMethods
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# The instance methods to install.
|
23
|
+
#
|
24
|
+
module InstanceMethods
|
25
|
+
#
|
26
|
+
# :category: CRUD
|
27
|
+
#
|
28
|
+
# Creates it.
|
29
|
+
# Reads itself from the response.
|
30
|
+
# Raises HttpError if the request is unsuccessful.
|
31
|
+
# options:: A hash of options to send with the request.
|
32
|
+
#
|
33
|
+
def create(options = {})
|
34
|
+
invalidate_uri
|
35
|
+
invalidate_options
|
36
|
+
options = @options.merge(options).merge(
|
37
|
+
body: serialize
|
38
|
+
)
|
39
|
+
response = self.class.put(@uri, options)
|
40
|
+
if response.success?
|
41
|
+
deserialize(response)
|
42
|
+
else
|
43
|
+
raise HttpError.new(response.response)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# A Resource can be created, read, updated and deleted.
|
4
|
+
#
|
5
|
+
class Resource < AbstractResource
|
6
|
+
#
|
7
|
+
# The identifier.
|
8
|
+
#
|
9
|
+
attr_accessor :id
|
10
|
+
|
11
|
+
#
|
12
|
+
# :category: CRUD
|
13
|
+
#
|
14
|
+
# Creates it.
|
15
|
+
# Must be overridden in a subclass.
|
16
|
+
# May use PutCreateable or PostCreateable.
|
17
|
+
# options:: A hash of options to send with the request.
|
18
|
+
#
|
19
|
+
def create(_options = {})
|
20
|
+
raise SubclassResponsibilityError.new
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# :category: CRUD
|
25
|
+
#
|
26
|
+
# Updates it.
|
27
|
+
# Reads itself from the response.
|
28
|
+
# Raises HttpError if the request is unsuccessful.
|
29
|
+
# options:: A hash of options to send with the request.
|
30
|
+
#
|
31
|
+
def update(options = {})
|
32
|
+
invalidate_uri
|
33
|
+
invalidate_options
|
34
|
+
options = @options.merge(options).merge(
|
35
|
+
body: serialize
|
36
|
+
)
|
37
|
+
response = self.class.put(@uri, options)
|
38
|
+
if response.success?
|
39
|
+
deserialize(response)
|
40
|
+
else
|
41
|
+
raise HttpError.new(response.response)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# :category: CRUD
|
47
|
+
#
|
48
|
+
# Deletes it.
|
49
|
+
# Reads itself from the response.
|
50
|
+
# Raises HttpError if the request is unsuccessful.
|
51
|
+
# options:: A hash of options to send with the request.
|
52
|
+
#
|
53
|
+
def delete(options = {})
|
54
|
+
invalidate_uri
|
55
|
+
invalidate_options
|
56
|
+
options = @options.merge(options)
|
57
|
+
response = self.class.delete(@uri, options)
|
58
|
+
if response.success?
|
59
|
+
deserialize(response)
|
60
|
+
else
|
61
|
+
raise HttpError.new(response.response)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# :category: Serialization
|
67
|
+
#
|
68
|
+
# Creates itself from a serializable representation, which only contains
|
69
|
+
# simple data types.
|
70
|
+
# serializable:: A hash with the keys:
|
71
|
+
# * uri:: The URI.
|
72
|
+
# * id:: The identifier.
|
73
|
+
#
|
74
|
+
def from_serializable(serializable)
|
75
|
+
super(serializable)
|
76
|
+
@id = serializable['id']
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# :category: Serialization
|
81
|
+
#
|
82
|
+
# Returns a serializable representation, which only contains simple data
|
83
|
+
# types.
|
84
|
+
# The hash has the keys:
|
85
|
+
# * uri:: The URI.
|
86
|
+
# * id:: The identifier.
|
87
|
+
#
|
88
|
+
def to_serializable
|
89
|
+
serializable = super
|
90
|
+
serializable['id'] = @id
|
91
|
+
serializable
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# A ResourcePage can be used to navigate through many resources of a type.
|
4
|
+
#
|
5
|
+
class ResourcePage < AbstractResource
|
6
|
+
#
|
7
|
+
# Raised when trying to get the next page from the last page.
|
8
|
+
#
|
9
|
+
class NoNextPageError < StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Raised when trying to get the previous page from the first page.
|
14
|
+
#
|
15
|
+
class NoPreviousPageError < StandardError
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# :attr: start
|
20
|
+
# The start index.
|
21
|
+
#
|
22
|
+
|
23
|
+
#
|
24
|
+
# :attr: end
|
25
|
+
# The end index.
|
26
|
+
#
|
27
|
+
|
28
|
+
#
|
29
|
+
# :attr: size
|
30
|
+
# The size.
|
31
|
+
#
|
32
|
+
|
33
|
+
#
|
34
|
+
# :attr: available
|
35
|
+
# The resources available.
|
36
|
+
#
|
37
|
+
|
38
|
+
#
|
39
|
+
# :attr: type
|
40
|
+
# The class of the resource to page.
|
41
|
+
#
|
42
|
+
|
43
|
+
#
|
44
|
+
# :attr: resources
|
45
|
+
# The resources.
|
46
|
+
#
|
47
|
+
|
48
|
+
attr_accessor :start, :end, :size, :available, :type, :resources
|
49
|
+
|
50
|
+
#
|
51
|
+
# Create a ResourcePage of the specified type.
|
52
|
+
# type:: The class of resource to page.
|
53
|
+
#
|
54
|
+
def initialize(type)
|
55
|
+
super()
|
56
|
+
@type = type
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# :category: CRUD
|
61
|
+
#
|
62
|
+
# Returns the next page.
|
63
|
+
# Raises NoNextPageError if the is none.
|
64
|
+
# options:: A hash of options to send with the request.
|
65
|
+
#
|
66
|
+
def next(options = {})
|
67
|
+
if @next.nil?
|
68
|
+
raise NoNextPageError.new
|
69
|
+
end
|
70
|
+
invalidate_options
|
71
|
+
options = @options.merge(options)
|
72
|
+
response = self.class.get(@next['href'], options)
|
73
|
+
if response.success?
|
74
|
+
page = self.class.new(@type)
|
75
|
+
page.deserialize(response)
|
76
|
+
page
|
77
|
+
else
|
78
|
+
raise HttpError.new(response.response)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# :category: CRUD
|
84
|
+
#
|
85
|
+
# Returns the previous page.
|
86
|
+
# Raises NoPreviousPageError if the is none.
|
87
|
+
# options:: A hash of options to send with the request.
|
88
|
+
#
|
89
|
+
def previous(options = {})
|
90
|
+
if @previous.nil?
|
91
|
+
raise NoPreviousPageError.new
|
92
|
+
end
|
93
|
+
invalidate_options
|
94
|
+
options = @options.merge(options)
|
95
|
+
response = self.class.get(@previous['href'], options)
|
96
|
+
if response.success?
|
97
|
+
page = self.class.new(@type)
|
98
|
+
page.deserialize(response)
|
99
|
+
page
|
100
|
+
else
|
101
|
+
raise HttpError.new(response.response)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# :category: Serialization
|
107
|
+
#
|
108
|
+
# Creates itself from a serializable representation, which only contains
|
109
|
+
# simple data types.
|
110
|
+
# serializable:: A hash with the keys:
|
111
|
+
# * uri:: The URI.
|
112
|
+
# * start:: The start index.
|
113
|
+
# * end:: The end index.
|
114
|
+
# * size:: The size.
|
115
|
+
# * available:: The resources available.
|
116
|
+
# * links:: Links as hashes with the keys:
|
117
|
+
# * description:: May be 'next' or 'previous'.
|
118
|
+
# * href:: The URI of the referenced page.
|
119
|
+
# * @plural_name:: Items mapped to the plural name of the @type.
|
120
|
+
#
|
121
|
+
def from_serializable(serializable)
|
122
|
+
super(serializable)
|
123
|
+
@start = serializable['start']
|
124
|
+
@end = serializable['end']
|
125
|
+
@size = serializable['size']
|
126
|
+
@available = serializable['available']
|
127
|
+
if serializable['links'].nil?
|
128
|
+
@next = nil
|
129
|
+
@previous = nil
|
130
|
+
else
|
131
|
+
@next = serializable['links'].find { |link| link['description'] == 'next' }
|
132
|
+
@previous = serializable['links'].find { |link| link['description'] == 'previous' }
|
133
|
+
end
|
134
|
+
@resources = serializable[plural_name].map do |resource_serializable|
|
135
|
+
resource = @type.new
|
136
|
+
resource.from_serializable(resource_serializable)
|
137
|
+
resource
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
#
|
142
|
+
# :category: Configuration
|
143
|
+
#
|
144
|
+
# Return the singular name of the type.
|
145
|
+
#
|
146
|
+
def singular_name
|
147
|
+
@type.new.singular_name
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# :category: Configuration
|
152
|
+
#
|
153
|
+
# Return the plural name of the type.
|
154
|
+
#
|
155
|
+
def plural_name
|
156
|
+
@type.new.plural_name
|
157
|
+
end
|
158
|
+
|
159
|
+
#
|
160
|
+
# :category: Configuration
|
161
|
+
#
|
162
|
+
# Return the resource's base URI of the type.
|
163
|
+
#
|
164
|
+
def resource_base_uri
|
165
|
+
@type.new.resource_base_uri
|
166
|
+
end
|
167
|
+
|
168
|
+
protected
|
169
|
+
|
170
|
+
#
|
171
|
+
# :category: Invalidation
|
172
|
+
#
|
173
|
+
# Sets the start and size attributes as query parameters.
|
174
|
+
#
|
175
|
+
def invalidate_options
|
176
|
+
@options[:query] = {
|
177
|
+
start: @start,
|
178
|
+
size: @size
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# :category: Invalidation
|
184
|
+
#
|
185
|
+
# Sets the URI to the types' base URI.
|
186
|
+
#
|
187
|
+
def invalidate_uri
|
188
|
+
@uri = resource_base_uri
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# Settings to access CyberCoach.
|
4
|
+
#
|
5
|
+
class Settings
|
6
|
+
#
|
7
|
+
# The URI to the server.
|
8
|
+
#
|
9
|
+
SERVER_URI = 'diufvm31.unifr.ch:8090'
|
10
|
+
|
11
|
+
#
|
12
|
+
# The URI to the resources, relative to the server URI.
|
13
|
+
#
|
14
|
+
BASE_URI = '/CyberCoachServer/resources'
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module CyberCoach
|
2
|
+
#
|
3
|
+
# A Sport has Subscriptions to which Entries are submitted.
|
4
|
+
#
|
5
|
+
class Sport < Resource
|
6
|
+
#
|
7
|
+
# It is pageable.
|
8
|
+
#
|
9
|
+
include Pageable
|
10
|
+
|
11
|
+
#
|
12
|
+
# :attr: name
|
13
|
+
# The name.
|
14
|
+
#
|
15
|
+
|
16
|
+
#
|
17
|
+
# :attr: description
|
18
|
+
# The description.
|
19
|
+
#
|
20
|
+
|
21
|
+
#
|
22
|
+
# :attr: subscriptions
|
23
|
+
# The Subscriptions to it.
|
24
|
+
#
|
25
|
+
|
26
|
+
attr_accessor :name, :description, :subscriptions
|
27
|
+
|
28
|
+
#
|
29
|
+
# :category: Serialization
|
30
|
+
#
|
31
|
+
# Creates itself from a serializable representation, which only contains
|
32
|
+
# simple data types.
|
33
|
+
# serializable:: A hash with the keys:
|
34
|
+
# * uri:: The URI.
|
35
|
+
# * id:: The identifier.
|
36
|
+
# * name:: The name.
|
37
|
+
# * description:: The description.
|
38
|
+
# * subscriptions:: Subscription serializables.
|
39
|
+
#
|
40
|
+
def from_serializable(serializable)
|
41
|
+
super(serializable)
|
42
|
+
@name = serializable['name']
|
43
|
+
@description = serializable['description']
|
44
|
+
@subscriptions = []
|
45
|
+
unless serializable['subscriptions'].nil?
|
46
|
+
@subscriptions = serializable['subscriptions'].map do
|
47
|
+
|subscription_serializable|
|
48
|
+
subscription = Subscription.new
|
49
|
+
subscription.from_serializable(subscription_serializable)
|
50
|
+
subscription
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# :category: Serialization
|
57
|
+
#
|
58
|
+
# Returns a serializable representation, which only contains simple data
|
59
|
+
# types.
|
60
|
+
# The hash has the keys:
|
61
|
+
# * uri:: The URI.
|
62
|
+
# * id:: The identifier.
|
63
|
+
# * name:: The name.
|
64
|
+
# * description:: The description.
|
65
|
+
#
|
66
|
+
def to_serializable
|
67
|
+
serializable = super
|
68
|
+
serializable['name'] = @name
|
69
|
+
serializable['description'] = @description
|
70
|
+
serializable
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# :category: Configuration
|
75
|
+
#
|
76
|
+
# Returns 'sport'.
|
77
|
+
#
|
78
|
+
def singular_name
|
79
|
+
'sport'
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# :category: Configuration
|
84
|
+
#
|
85
|
+
# Returns 'sports'.
|
86
|
+
#
|
87
|
+
def plural_name
|
88
|
+
'sports'
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
#
|
94
|
+
# :category: Invalidation
|
95
|
+
#
|
96
|
+
# Sets the uri to the base uri and the name.
|
97
|
+
#
|
98
|
+
def invalidate_uri
|
99
|
+
unless @name.nil?
|
100
|
+
@uri = "#{resource_base_uri}#{@name}/"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|