verso 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.md +10 -22
- data/lib/verso.rb +10 -2
- data/lib/verso/base.rb +50 -0
- data/lib/verso/cluster.rb +55 -25
- data/lib/verso/cluster_list.rb +15 -10
- data/lib/verso/correlation_list.rb +30 -40
- data/lib/verso/course.rb +106 -43
- data/lib/verso/course_list.rb +57 -21
- data/lib/verso/credential.rb +94 -20
- data/lib/verso/credential_list.rb +30 -15
- data/lib/verso/duty_area.rb +23 -10
- data/lib/verso/edition_list.rb +18 -10
- data/lib/verso/emphasis.rb +26 -12
- data/lib/verso/emphasis_list.rb +18 -10
- data/lib/verso/examination_list.rb +28 -12
- data/lib/verso/extra.rb +34 -32
- data/lib/verso/extras_list.rb +28 -12
- data/lib/verso/frontmatter.rb +43 -11
- data/lib/verso/hash.rb +19 -0
- data/lib/verso/http_gettable.rb +31 -0
- data/lib/verso/occupation.rb +36 -14
- data/lib/verso/occupation_data.rb +35 -14
- data/lib/verso/occupation_list.rb +23 -20
- data/lib/verso/pathway.rb +32 -14
- data/lib/verso/program_area.rb +42 -21
- data/lib/verso/program_area_list.rb +15 -11
- data/lib/verso/standard.rb +45 -23
- data/lib/verso/standards_list.rb +41 -30
- data/lib/verso/task.rb +52 -17
- data/lib/verso/task_list.rb +40 -17
- data/lib/verso/version.rb +1 -1
- data/spec/cluster_list_spec.rb +78 -5
- data/spec/cluster_spec.rb +106 -9
- data/spec/correlation_list_spec.rb +108 -50
- data/spec/course_list_spec.rb +112 -23
- data/spec/course_spec.rb +321 -127
- data/spec/credential_list_spec.rb +83 -52
- data/spec/credential_spec.rb +358 -19
- data/spec/duty_area_spec.rb +47 -17
- data/spec/edition_list_spec.rb +90 -4
- data/spec/emphasis_list_spec.rb +75 -11
- data/spec/emphasis_spec.rb +37 -21
- data/spec/examination_list_spec.rb +146 -20
- data/spec/extra_spec.rb +61 -22
- data/spec/extras_list_spec.rb +80 -17
- data/spec/frontmatter_spec.rb +141 -6
- data/spec/hash_spec.rb +49 -0
- data/spec/occupation_data_spec.rb +31 -13
- data/spec/occupation_list_spec.rb +88 -15
- data/spec/occupation_spec.rb +72 -28
- data/spec/pathway_spec.rb +47 -27
- data/spec/program_area_list_spec.rb +78 -4
- data/spec/program_area_spec.rb +70 -22
- data/spec/standard_spec.rb +94 -36
- data/spec/standards_list_spec.rb +130 -36
- data/spec/task_list_spec.rb +160 -51
- data/spec/task_spec.rb +120 -33
- data/verso.gemspec +3 -1
- metadata +41 -17
- data/lib/verso/http_get.rb +0 -9
- data/lib/verso/sol_correlation_list.rb +0 -53
- data/spec/sol_correlation_list_spec.rb +0 -74
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -6,8 +6,7 @@ Technical Education curriculum, course, and occupation data.
|
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
-
The verso gem has been tested with Ruby 1.9.3
|
10
|
-
Ruby 1.8.7.
|
9
|
+
The verso gem has been tested with Ruby 1.9.3 and 1.8.7.
|
11
10
|
|
12
11
|
gem install verso
|
13
12
|
|
@@ -17,28 +16,17 @@ Ruby 1.8.7.
|
|
17
16
|
cd verso
|
18
17
|
rake install
|
19
18
|
|
20
|
-
##
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
instance collection objects do not always respond to all the expected
|
28
|
-
methods -- `#to_a` is your friend), the specs are incomplete, and the
|
29
|
-
documentation is nil.
|
30
|
-
|
31
|
-
All that said, the wrapper is reasonably complete, and should make a great
|
32
|
-
starting pointing for getting course, curriculum, and occupation data out of
|
33
|
-
Verso. The classes available in lib/verso correspond to the resources described
|
34
|
-
in the [API documentation](http://api.cteresource.org/docs). The usual points
|
35
|
-
of entry are the [Cluster List](http://api.cteresource.org/docs/clusters), the
|
19
|
+
## Quick Start
|
20
|
+
|
21
|
+
The wrapper should make a great starting pointing for getting course,
|
22
|
+
curriculum, and occupation data out of Verso. The classes available in
|
23
|
+
lib/verso correspond to the resources described in the [API
|
24
|
+
documentation](http://api.cteresource.org/docs). The usual points of entry
|
25
|
+
are the [Cluster List](http://api.cteresource.org/docs/clusters), the
|
36
26
|
[Course List](http://api.cteresource.org/docs/courses), the [Occupation
|
37
27
|
List](http://api.cteresource.org/docs/occupations), and the [Credential
|
38
28
|
List](http://api.cteresource.org/docs/credentials).
|
39
29
|
|
40
|
-
## Quick Start
|
41
|
-
|
42
30
|
### Start with Clusters
|
43
31
|
|
44
32
|
require 'verso'
|
@@ -51,8 +39,8 @@ List](http://api.cteresource.org/docs/credentials).
|
|
51
39
|
|
52
40
|
require 'verso'
|
53
41
|
course = Verso::CourseList.new(:code => "6321").first
|
54
|
-
course.title # => "
|
55
|
-
da = course.duty_areas
|
42
|
+
course.title # => "Accounting, Advanced"
|
43
|
+
da = course.duty_areas[5]
|
56
44
|
da.title # => "Using Technology to Implement Accounting Procedures"
|
57
45
|
da.tasks.last.statement # => "Apply emerging technology trends used in the accounting profession."
|
58
46
|
|
data/lib/verso.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
# external
|
1
2
|
require 'addressable/uri'
|
3
|
+
require 'forwardable'
|
2
4
|
require 'json'
|
3
5
|
require 'net/http'
|
4
6
|
require 'ostruct'
|
5
7
|
|
6
|
-
|
8
|
+
# base/mixin/override
|
9
|
+
require 'verso/base'
|
10
|
+
require 'verso/hash'
|
11
|
+
require 'verso/http_gettable'
|
12
|
+
|
13
|
+
# resources and children
|
7
14
|
require 'verso/cluster'
|
8
15
|
require 'verso/cluster_list'
|
9
16
|
require 'verso/correlation_list'
|
@@ -25,9 +32,10 @@ require 'verso/occupation_list'
|
|
25
32
|
require 'verso/pathway'
|
26
33
|
require 'verso/program_area_list'
|
27
34
|
require 'verso/program_area'
|
28
|
-
require 'verso/sol_correlation_list'
|
29
35
|
require 'verso/standard'
|
30
36
|
require 'verso/standards_list'
|
31
37
|
require 'verso/task'
|
32
38
|
require 'verso/task_list'
|
39
|
+
|
40
|
+
# gem version
|
33
41
|
require 'verso/version'
|
data/lib/verso/base.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# A wrapper for the Virginia CTE Resource Center's Web API, providing access
|
2
|
+
# to Virginia's Career and Technical Education curriculum, course, and
|
3
|
+
# occupation data.
|
4
|
+
#
|
5
|
+
# @see http://api.cteresource.org/docs Web API documentation
|
6
|
+
module Verso
|
7
|
+
# @abstract Classes derived from Verso::Base should define attr_readers or
|
8
|
+
# appropriate methods (using Verso::Base#get_attr w/in methods) to access
|
9
|
+
# attributes stored in the attrs hash.
|
10
|
+
#
|
11
|
+
# @!attribute [r] attrs
|
12
|
+
# attribute hash
|
13
|
+
class Base
|
14
|
+
attr_reader :attrs
|
15
|
+
alias to_hash attrs
|
16
|
+
|
17
|
+
# Initialize new object
|
18
|
+
#
|
19
|
+
# @param attrs [Hash]
|
20
|
+
# @return [Verso::Base]
|
21
|
+
def initialize(attrs={})
|
22
|
+
@attrs = attrs.symbolize_nested_keys!
|
23
|
+
end
|
24
|
+
|
25
|
+
# Define methods to retrieve values from attribute hash
|
26
|
+
#
|
27
|
+
# @param attrs [Symbol]
|
28
|
+
def self.attr_reader(*attrs)
|
29
|
+
attrs.each do |attr|
|
30
|
+
class_eval do
|
31
|
+
define_method attr do
|
32
|
+
get_attr(attr.to_sym)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
# Get attribute value from attrs attribute store or raise NoMethodError
|
41
|
+
# if the key is not defined.
|
42
|
+
#
|
43
|
+
# @param attr [Symbol]
|
44
|
+
# @return attribute value
|
45
|
+
# @raise [NoMethodError]
|
46
|
+
def get_attr(attr)
|
47
|
+
attrs.has_key?(attr) ? attrs[attr] : method_missing(attr)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/verso/cluster.rb
CHANGED
@@ -1,43 +1,73 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Career Cluster Resource
|
3
|
+
#
|
4
|
+
# @see http://api.cteresource.org/docs/clusters/cluster
|
5
|
+
# @see http://www.careertech.org/career-clusters/glance/clusters.html
|
6
|
+
#
|
7
|
+
# @!attribute [r] code
|
8
|
+
# @return [String] Cluster code
|
9
|
+
# @!attribute [r] description
|
10
|
+
# @return [String] HTML-formatted Cluster description
|
11
|
+
# @!attribute [r] id
|
12
|
+
# @return [Fixnum] Cluster id
|
13
|
+
# @!attribute [r] postsecondary_info
|
14
|
+
# @return [String] HTML-formatted postsecondary preparation info
|
15
|
+
#
|
16
|
+
# @overload initialize(attrs={})
|
17
|
+
# @note Any attributes may be set upon instantiation, using Options Hash.
|
18
|
+
# The following are required:
|
19
|
+
# @option attrs [Fixnum] :id Cluster id *Required*
|
20
|
+
class Cluster < Verso::Base
|
21
|
+
include HTTPGettable
|
22
|
+
attr_reader :code, :description, :id, :postsecondary_info
|
4
23
|
|
5
|
-
|
6
|
-
|
24
|
+
# Return VDOE Cluster contact. The contact will respond to #name, #email,
|
25
|
+
# and #phone, returning Strings.
|
26
|
+
#
|
27
|
+
# @return [OpenStruct]
|
28
|
+
def contact
|
29
|
+
@contact ||= OpenStruct.new(get_attr(:contact))
|
7
30
|
end
|
8
31
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@
|
32
|
+
# Courses related to the Cluster
|
33
|
+
#
|
34
|
+
# @return [Verso::CourseList]
|
35
|
+
def courses
|
36
|
+
@courses ||= CourseList.new(:cluster => slug.gsub('-', ' ')).
|
37
|
+
sort_by { |c| c.title + c.edition }.
|
38
|
+
uniq { |c| c.code + c.edition }
|
14
39
|
end
|
15
40
|
|
16
|
-
|
17
|
-
|
41
|
+
# The Cluster's Pathways
|
42
|
+
#
|
43
|
+
# @see http://www.careertech.org/career-clusters/clusters-occupations.html
|
44
|
+
# @see Verso::Pathway
|
45
|
+
#
|
46
|
+
# @return [Array]
|
47
|
+
def pathways
|
48
|
+
@pathways ||= get_attr(:pathways).
|
49
|
+
collect { |p| Pathway.new(p) }
|
18
50
|
end
|
19
51
|
|
20
|
-
|
21
|
-
|
52
|
+
# @return [String] parameterized title
|
53
|
+
def slug
|
54
|
+
title.parameterize
|
22
55
|
end
|
23
56
|
|
24
|
-
|
25
|
-
|
57
|
+
# @return [String] Cluster title
|
58
|
+
def title
|
59
|
+
@title ||= attrs[:title] || attrs[:cluster][:title]
|
26
60
|
end
|
27
61
|
|
28
|
-
|
29
|
-
@raw_cluster["title"].parameterize
|
30
|
-
end
|
62
|
+
private
|
31
63
|
|
32
|
-
def
|
33
|
-
|
34
|
-
collect { |p| Pathway.new(p) }
|
64
|
+
def fetch
|
65
|
+
super[:cluster]
|
35
66
|
end
|
36
67
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
uniq { |c| c.code + c.edition }
|
68
|
+
# @return [String] URI for Cluster resource
|
69
|
+
def path
|
70
|
+
"/clusters/#{id}"
|
41
71
|
end
|
42
72
|
end
|
43
73
|
end
|
data/lib/verso/cluster_list.rb
CHANGED
@@ -1,19 +1,24 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Career Cluster List Resource
|
3
|
+
#
|
4
|
+
# A collection of {Verso::Cluster} objects
|
5
|
+
#
|
6
|
+
# @see http://api.cteresource.org/docs/clusters
|
7
|
+
# @see http://www.careertech.org/career-clusters/glance/clusters.html
|
8
|
+
class ClusterList < Verso::Base
|
3
9
|
include Enumerable
|
4
|
-
include
|
10
|
+
include HTTPGettable
|
11
|
+
extend Forwardable
|
12
|
+
def_delegators :clusters, :[], :each, :empty?, :last, :length
|
5
13
|
|
6
|
-
|
7
|
-
@clusters ||= JSON.parse(http_get('/clusters/'))["clusters"].
|
8
|
-
collect { |c| Cluster.new(c) }
|
9
|
-
end
|
14
|
+
private
|
10
15
|
|
11
|
-
def
|
12
|
-
clusters.
|
16
|
+
def clusters
|
17
|
+
@clusters ||= get_attr(:clusters).collect { |c| Cluster.new(c) }
|
13
18
|
end
|
14
19
|
|
15
|
-
def
|
16
|
-
clusters
|
20
|
+
def path
|
21
|
+
"/clusters/"
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
@@ -1,53 +1,43 @@
|
|
1
1
|
module Verso
|
2
|
-
|
2
|
+
# Correlation List Resource
|
3
|
+
#
|
4
|
+
# A crosswalk of competencies to standards body goals.
|
5
|
+
# @see http://api.cteresource.org/docs/courses/course/standards/standard/correlations
|
6
|
+
#
|
7
|
+
# @!attribute [r] code
|
8
|
+
# @return [String] Course code
|
9
|
+
# @!attribute [r] edition
|
10
|
+
# @return [String] Edition year
|
11
|
+
# @!attribute [r] name
|
12
|
+
# @return [String] Standards Body name, used as an identifier and not to
|
13
|
+
# be confused with its title
|
14
|
+
#
|
15
|
+
# @overload initialize(attrs={})
|
16
|
+
# @note Certain attributes are required for instantiation.
|
17
|
+
# @option attrs [String] :code Course code *Required*
|
18
|
+
# @option attrs [String] :edition Edition year *Required*
|
19
|
+
# @option attrs [String] :name Standards Body name *Required*
|
20
|
+
class CorrelationList < Verso::Base
|
3
21
|
include Enumerable
|
4
|
-
include
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
@name = name
|
9
|
-
end
|
22
|
+
include HTTPGettable
|
23
|
+
extend Forwardable
|
24
|
+
def_delegators :correlations, :[], :each, :empty?, :last, :length
|
25
|
+
attr_reader :code, :edition, :name
|
10
26
|
|
27
|
+
# @return [String] Standards body title
|
11
28
|
def title
|
12
|
-
@title ||=
|
29
|
+
@title ||= first.goals.first.title
|
13
30
|
end
|
14
31
|
|
15
|
-
|
16
|
-
@context.code
|
17
|
-
end
|
18
|
-
|
19
|
-
def edition
|
20
|
-
@context.edition
|
21
|
-
end
|
22
|
-
|
23
|
-
def tasklist
|
24
|
-
@context.duty_areas
|
25
|
-
end
|
26
|
-
|
27
|
-
def sol_names
|
28
|
-
@sol_names ||= @context.standards.sols.collect { |s| s.name }
|
29
|
-
end
|
32
|
+
private
|
30
33
|
|
31
34
|
def correlations
|
32
|
-
@correlations ||=
|
33
|
-
|
34
|
-
)["correlations"]
|
35
|
+
@correlations ||= get_attr(:correlations).
|
36
|
+
collect { |c| Task.new(c.merge(:code => code, :edition => edition)) }
|
35
37
|
end
|
36
38
|
|
37
|
-
def
|
38
|
-
|
39
|
-
tasklist.each do |da|
|
40
|
-
da.tasks.each do |task|
|
41
|
-
count += 1
|
42
|
-
related = correlations.find { |c| c["id"] == task.id }
|
43
|
-
if related.nil?
|
44
|
-
next
|
45
|
-
else
|
46
|
-
related["number"] = count
|
47
|
-
yield Task.new(related)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
39
|
+
def path
|
40
|
+
"/courses/#{code},#{edition}/standards/#{name}/correlations"
|
51
41
|
end
|
52
42
|
end
|
53
43
|
end
|
data/lib/verso/course.rb
CHANGED
@@ -1,23 +1,79 @@
|
|
1
1
|
module Verso
|
2
|
-
|
3
|
-
|
2
|
+
# Course Resource
|
3
|
+
#
|
4
|
+
# The chief container of Virginia CTE course data and the *parent of
|
5
|
+
# curriculum data.
|
6
|
+
#
|
7
|
+
# @see http://api.cteresource.org/docs/courses/course
|
8
|
+
#
|
9
|
+
# @!attribute [r] co_op
|
10
|
+
# @return [Boolean] Is this a co-op course?
|
11
|
+
# @!attribute [r] code
|
12
|
+
# @return [String] Course code
|
13
|
+
# @!attribute [r] complement
|
14
|
+
# @return [Boolean] Is this a complementary course?
|
15
|
+
# @!attribute [r] description
|
16
|
+
# @return [String] HTML-formatted course description
|
17
|
+
# @!attribute [r] duration
|
18
|
+
# @return [Fixnum] Course duration in weeks
|
19
|
+
# @!attribute [r] edition
|
20
|
+
# @return [String] Edition year
|
21
|
+
# @!attribute [r] grade_levels
|
22
|
+
# @return [String] Space-separated list of recommended grade levels
|
23
|
+
# @!attribute [r] hours
|
24
|
+
# @return [nil,Fixnum] Course hours
|
25
|
+
# @!attribute [r] hs_credit_in_ms
|
26
|
+
# @return [Boolean] High school credit in middle school?
|
27
|
+
# @!attribute [r] osha_exempt
|
28
|
+
# @return [Boolean] Is this course exempt from the OSHA memo?
|
29
|
+
# @!attribute [r] related_resources
|
30
|
+
# @return [Array] Array of strings specifying related resources
|
31
|
+
# @see http://api.cteresource.org/docs/courses/course
|
32
|
+
# @!attribute [r] title
|
33
|
+
# @return [String] Course title
|
34
|
+
#
|
35
|
+
# @overload initialize(attrs={})
|
36
|
+
# @note Any attributes may be set upon instantiation, using Options Hash.
|
37
|
+
# The following are required:
|
38
|
+
# @option attrs [String] :code Course code *Required*
|
39
|
+
# @option attrs [String] :edition Edition year *Required*
|
40
|
+
class Course < Verso::Base
|
41
|
+
include HTTPGettable
|
42
|
+
attr_reader :co_op, :code, :complement, :description, :duration,
|
43
|
+
:edition, :grade_levels, :hours, :hs_credit_in_ms, :osha_exempt,
|
44
|
+
:related_resources, :title
|
45
|
+
alias co_op? co_op
|
46
|
+
alias complement? complement
|
47
|
+
alias hs_credit_in_ms? hs_credit_in_ms
|
48
|
+
alias osha_exempt? osha_exempt
|
4
49
|
|
5
|
-
|
6
|
-
|
50
|
+
# @return [Array] Collection of certification {Verso::Credential} objects
|
51
|
+
def certifications
|
52
|
+
@certfications ||= credentials.select { |c| c.type == "Certification" }
|
7
53
|
end
|
8
54
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
@raw_course.has_key?(mname.to_s) ? @raw_course[mname.to_s] : super
|
55
|
+
# @return [Array] Collection of {Verso::Credential} objects
|
56
|
+
def credentials
|
57
|
+
@credentials ||= get_attr(:credentials).collect { |c| Credential.new(c) }
|
14
58
|
end
|
15
59
|
|
16
|
-
|
17
|
-
|
18
|
-
|
60
|
+
# @return [Verso::TaskList] TaskList is a collection of {Verso::DutyArea}
|
61
|
+
# objects.
|
62
|
+
def duty_areas
|
63
|
+
@duty_areas ||= TaskList.new(:code => code, :edition => edition)
|
64
|
+
end
|
65
|
+
alias tasklist duty_areas
|
66
|
+
|
67
|
+
# @return [Verso::ExtrasList]
|
68
|
+
def extras
|
69
|
+
@extras ||= if related_resources.include?("extras")
|
70
|
+
ExtrasList.new(:code => code, :edition => edition)
|
71
|
+
else
|
72
|
+
[]
|
73
|
+
end
|
19
74
|
end
|
20
75
|
|
76
|
+
# @return [Verso:Frontmatter]
|
21
77
|
def frontmatter
|
22
78
|
@frontmatter ||= if self.related_resources.include?("frontmatter")
|
23
79
|
Frontmatter.new("code" => code, "edition" => edition)
|
@@ -26,59 +82,66 @@ module Verso
|
|
26
82
|
end
|
27
83
|
end
|
28
84
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def occupation_data
|
34
|
-
@occupation_data ||= method_missing(:occupation_data).
|
35
|
-
collect { |od| OccupationData.new(od) }
|
85
|
+
# @return [Boolean] Is this a middle school course?
|
86
|
+
def is_ms?
|
87
|
+
grade_levels.split.first.to_i < 9
|
36
88
|
end
|
37
89
|
|
38
|
-
|
39
|
-
|
90
|
+
# @return [Boolean] is this a high school course?
|
91
|
+
def is_hs?
|
92
|
+
grade_levels.split.last.to_i > 8
|
40
93
|
end
|
41
94
|
|
42
|
-
|
43
|
-
|
44
|
-
|
95
|
+
# @return [Array] Colection of license {Verso::Credential} objects
|
96
|
+
def licenses
|
97
|
+
@licenses ||= credentials.select { |c| c.type == "License" }
|
45
98
|
end
|
46
99
|
|
47
|
-
|
48
|
-
|
49
|
-
|
100
|
+
# @return [Array] Collection of prerequisite {Verso::Course} objects
|
101
|
+
def prerequisite_courses
|
102
|
+
@prerequisites ||= get_attr(:prerequisite_courses).
|
103
|
+
collect { |c| Course.new(c) }
|
50
104
|
end
|
105
|
+
alias prerequisites prerequisite_courses
|
51
106
|
|
52
|
-
|
53
|
-
|
107
|
+
# @return [Array] Collection of {Verso::OccupationData} objects
|
108
|
+
def occupation_data
|
109
|
+
@occupation_data ||= get_attr(:occupation_data).
|
110
|
+
collect { |od| OccupationData.new(od) }
|
54
111
|
end
|
55
112
|
|
56
|
-
|
57
|
-
|
113
|
+
# @return [Array] Collection of related {Verso::Course} objects
|
114
|
+
# forming sequences with this course.
|
115
|
+
def related_courses
|
116
|
+
@related_courses ||= get_attr(:related_courses).
|
117
|
+
collect { |c| Course.new(c) }
|
58
118
|
end
|
59
119
|
|
120
|
+
# @return [Verso::StandardsList] Standards bodies correlated to this
|
121
|
+
# course's tasks.
|
60
122
|
def standards
|
61
123
|
@standards ||= if self.related_resources.include?("standards")
|
62
124
|
StandardsList.from_course(self)
|
63
125
|
else
|
64
|
-
StandardsList.new(
|
126
|
+
StandardsList.new(:code => code, :edition => edition,
|
127
|
+
:standards => [])
|
65
128
|
end
|
66
129
|
end
|
67
130
|
|
68
|
-
|
69
|
-
|
131
|
+
# Fetch a complete task given a task id.
|
132
|
+
#
|
133
|
+
# @param [Fixnum] tid The task id
|
134
|
+
# @return [Verso::Task]
|
135
|
+
def task(tid)
|
136
|
+
@tasks ||= {}
|
137
|
+
@tasks[tid] ||= Task.new("code" => code, "edition" => edition,
|
138
|
+
"id" => tid)
|
70
139
|
end
|
71
140
|
|
72
|
-
|
73
|
-
grade_levels.split.last.to_i > 8
|
74
|
-
end
|
141
|
+
private
|
75
142
|
|
76
|
-
def
|
77
|
-
|
78
|
-
ExtrasList.new(:code => code, :edition => edition)
|
79
|
-
else
|
80
|
-
[]
|
81
|
-
end
|
143
|
+
def path
|
144
|
+
"/courses/#{code},#{edition}"
|
82
145
|
end
|
83
146
|
end
|
84
147
|
end
|