clever-ruby 0.6.2 → 0.7.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 +8 -8
 - data/CHANGELOG.md +5 -0
 - data/lib/clever-ruby.rb +3 -0
 - data/lib/clever-ruby/api_operations/nested_list.rb +46 -0
 - data/lib/clever-ruby/api_resource.rb +67 -27
 - data/lib/clever-ruby/clever_object.rb +8 -2
 - data/lib/clever-ruby/district.rb +25 -11
 - data/lib/clever-ruby/event.rb +1 -1
 - data/lib/clever-ruby/nested_resource.rb +40 -0
 - data/lib/clever-ruby/school.rb +1 -1
 - data/lib/clever-ruby/section.rb +1 -1
 - data/lib/clever-ruby/student.rb +13 -1
 - data/lib/clever-ruby/teacher.rb +1 -1
 - data/lib/clever-ruby/util.rb +16 -17
 - data/lib/clever-ruby/version.rb +1 -1
 - data/test/data/vcr_cassettes/district_count.yml +6 -6
 - data/test/data/vcr_cassettes/{districts_events.yml → district_events.yml} +29 -164
 - data/test/data/vcr_cassettes/district_find_by_page.yml +12 -12
 - data/test/data/vcr_cassettes/district_find_multiple.yml +12 -12
 - data/test/data/vcr_cassettes/district_find_one.yml +12 -12
 - data/test/data/vcr_cassettes/{districts_schools.yml → district_schools.yml} +25 -148
 - data/test/data/vcr_cassettes/district_sections.yml +2289 -0
 - data/test/data/vcr_cassettes/district_students.yml +2339 -0
 - data/test/data/vcr_cassettes/{districts_teachers.yml → district_teachers.yml} +25 -148
 - data/test/data/vcr_cassettes/districts.yml +12 -12
 - data/test/data/vcr_cassettes/districts_event_pages.yml +76 -469
 - data/test/data/vcr_cassettes/districts_school_pages.yml +31 -154
 - data/test/data/vcr_cassettes/districts_section_pages.yml +284 -407
 - data/test/data/vcr_cassettes/districts_student_pages.yml +165 -288
 - data/test/data/vcr_cassettes/districts_teacher_pages.yml +81 -204
 - data/test/data/vcr_cassettes/error_handling.yml +17 -58
 - data/test/data/vcr_cassettes/event_count.yml +7 -7
 - data/test/data/vcr_cassettes/event_find_by_page.yml +16 -22
 - data/test/data/vcr_cassettes/event_find_multiple.yml +19 -28
 - data/test/data/vcr_cassettes/event_find_one.yml +16 -22
 - data/test/data/vcr_cassettes/events.yml +16 -22
 - data/test/data/vcr_cassettes/school_count.yml +6 -6
 - data/test/data/vcr_cassettes/school_district.yml +140 -0
 - data/test/data/vcr_cassettes/school_events.yml +181 -0
 - data/test/data/vcr_cassettes/school_find_by_page.yml +13 -13
 - data/test/data/vcr_cassettes/school_find_multiple.yml +14 -14
 - data/test/data/vcr_cassettes/school_find_one.yml +13 -13
 - data/test/data/vcr_cassettes/school_sections.yml +1119 -0
 - data/test/data/vcr_cassettes/school_students.yml +1033 -0
 - data/test/data/vcr_cassettes/school_teachers.yml +257 -0
 - data/test/data/vcr_cassettes/schools.yml +13 -13
 - data/test/data/vcr_cassettes/schools_optional_attributes.yml +7 -7
 - data/test/data/vcr_cassettes/section_count.yml +6 -6
 - data/test/data/vcr_cassettes/section_district.yml +393 -0
 - data/test/data/vcr_cassettes/section_events.yml +434 -0
 - data/test/data/vcr_cassettes/section_find_by_page.yml +34 -34
 - data/test/data/vcr_cassettes/section_find_multiple.yml +14 -14
 - data/test/data/vcr_cassettes/section_find_one.yml +14 -14
 - data/test/data/vcr_cassettes/section_school.yml +396 -0
 - data/test/data/vcr_cassettes/section_students.yml +456 -0
 - data/test/data/vcr_cassettes/section_teacher.yml +394 -0
 - data/test/data/vcr_cassettes/sections.yml +34 -34
 - data/test/data/vcr_cassettes/student_count.yml +6 -6
 - data/test/data/vcr_cassettes/student_district.yml +202 -0
 - data/test/data/vcr_cassettes/student_events.yml +243 -0
 - data/test/data/vcr_cassettes/student_find_by_page.yml +83 -83
 - data/test/data/vcr_cassettes/student_find_multiple.yml +14 -14
 - data/test/data/vcr_cassettes/student_find_one.yml +14 -14
 - data/test/data/vcr_cassettes/student_school.yml +205 -0
 - data/test/data/vcr_cassettes/student_sections.yml +269 -0
 - data/test/data/vcr_cassettes/student_teacher.yml +161 -0
 - data/test/data/vcr_cassettes/student_teachers.yml +245 -0
 - data/test/data/vcr_cassettes/students.yml +83 -83
 - data/test/data/vcr_cassettes/teacher_count.yml +6 -6
 - data/test/data/vcr_cassettes/teacher_district.yml +218 -0
 - data/test/data/vcr_cassettes/teacher_events.yml +259 -0
 - data/test/data/vcr_cassettes/teacher_find_by_page.yml +13 -13
 - data/test/data/vcr_cassettes/teacher_find_multiple.yml +14 -14
 - data/test/data/vcr_cassettes/teacher_find_one.yml +13 -13
 - data/test/data/vcr_cassettes/teacher_school.yml +221 -0
 - data/test/data/vcr_cassettes/teacher_sections.yml +291 -0
 - data/test/data/vcr_cassettes/teacher_students.yml +293 -0
 - data/test/data/vcr_cassettes/teachers.yml +13 -13
 - data/test/integration/api_operations/list_test.rb +1 -1
 - data/test/integration/district_test.rb +17 -49
 - data/test/integration/error_handling_test.rb +1 -1
 - data/test/integration/nested_resource_test.rb +27 -0
 - data/test/unit/api_resource_test.rb +32 -0
 - data/test/unit/optional_attributes_test.rb +7 -13
 - metadata +60 -14
 - data/test/data/vcr_cassettes/districts_sections.yml +0 -818
 - data/test/data/vcr_cassettes/districts_students.yml +0 -436
 - data/test/data/vcr_cassettes/districts_students_filtered.yml +0 -170
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,15 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            !binary "U0hBMQ==":
         
     | 
| 
       3 
3 
     | 
    
         
             
              metadata.gz: !binary |-
         
     | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
      
 4 
     | 
    
         
            +
                NTMxM2FkNGQzYzQ0YTJjZjE0YzhkMGM0ZDAyNjg2MTg3MjFlYzU0Ng==
         
     | 
| 
       5 
5 
     | 
    
         
             
              data.tar.gz: !binary |-
         
     | 
| 
       6 
     | 
    
         
            -
                 
     | 
| 
      
 6 
     | 
    
         
            +
                NDgzOWE5NzdhZjM2NWY4YjQyNzU1ZjY1NWQ5YThiZDlkM2IzNzgyYg==
         
     | 
| 
       7 
7 
     | 
    
         
             
            SHA512:
         
     | 
| 
       8 
8 
     | 
    
         
             
              metadata.gz: !binary |-
         
     | 
| 
       9 
     | 
    
         
            -
                 
     | 
| 
       10 
     | 
    
         
            -
                 
     | 
| 
       11 
     | 
    
         
            -
                 
     | 
| 
      
 9 
     | 
    
         
            +
                ODIyYTg2NTQwOTA4YWUyNjgxNjhhNjU3ZTk1YWNhYmMyZTA3NjYzM2NhZGJj
         
     | 
| 
      
 10 
     | 
    
         
            +
                NGI2YWJlOTkyZTFhMTI0ZjlmN2U2MzExNzgyYjliY2JmN2Y1YzZhM2NmZjk0
         
     | 
| 
      
 11 
     | 
    
         
            +
                ZjY2MjgzODk0ZWNiOTM3YjI5N2EyNDUxZmY5MTIxYTlmNTM0YTA=
         
     | 
| 
       12 
12 
     | 
    
         
             
              data.tar.gz: !binary |-
         
     | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
                 
     | 
| 
      
 13 
     | 
    
         
            +
                YjE5MzgwMTJiMWRjYTYyMjQ3N2MzOTMwM2VkODcxZTViZjdhNTkyYjM0Y2Iw
         
     | 
| 
      
 14 
     | 
    
         
            +
                Y2FjMjE2MjI2ZGQ4MWFlNTkwZWVmMDMxZTM1ZTBkZDkzYTkwZTc1OGY1OGVj
         
     | 
| 
      
 15 
     | 
    
         
            +
                NzNiOGFmN2U1OTNkYzhhMjAxNDg3ZWIzZjIwNzFiNWU3MDljZmU=
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/lib/clever-ruby.rb
    CHANGED
    
    | 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # rubocop:disable FileName
         
     | 
| 
       2 
2 
     | 
    
         
             
            require 'rest_client'
         
     | 
| 
       3 
3 
     | 
    
         
             
            require 'multi_json'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'active_support/inflector'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require 'open-uri'
         
     | 
| 
       5 
6 
     | 
    
         
             
            require 'set'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require 'uri'
         
     | 
| 
         @@ -10,6 +11,7 @@ require 'clever-ruby/version' 
     | 
|
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
            # API operations
         
     | 
| 
       12 
13 
     | 
    
         
             
            require 'clever-ruby/api_operations/list'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require 'clever-ruby/api_operations/nested_list'
         
     | 
| 
       13 
15 
     | 
    
         
             
            require 'clever-ruby/api_operations/pagelist'
         
     | 
| 
       14 
16 
     | 
    
         
             
            require 'clever-ruby/api_operations/results_list'
         
     | 
| 
       15 
17 
     | 
    
         
             
            require 'clever-ruby/api_operations/page'
         
     | 
| 
         @@ -22,6 +24,7 @@ require 'clever-ruby/configuration' 
     | 
|
| 
       22 
24 
     | 
    
         
             
            # Resources
         
     | 
| 
       23 
25 
     | 
    
         
             
            require 'clever-ruby/clever_object'
         
     | 
| 
       24 
26 
     | 
    
         
             
            require 'clever-ruby/api_resource'
         
     | 
| 
      
 27 
     | 
    
         
            +
            require 'clever-ruby/nested_resource'
         
     | 
| 
       25 
28 
     | 
    
         
             
            require 'clever-ruby/district'
         
     | 
| 
       26 
29 
     | 
    
         
             
            require 'clever-ruby/school'
         
     | 
| 
       27 
30 
     | 
    
         
             
            require 'clever-ruby/student'
         
     | 
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Clever
         
     | 
| 
      
 2 
     | 
    
         
            +
              module APIOperations
         
     | 
| 
      
 3 
     | 
    
         
            +
                # Methods for interacting with the API on nested resources
         
     | 
| 
      
 4 
     | 
    
         
            +
                module NestedList
         
     | 
| 
      
 5 
     | 
    
         
            +
                  # Query a nested list with Clever API params, overriding initialized keys
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # @note You don't need to call this if you aren't using additional filters;
         
     | 
| 
      
 8 
     | 
    
         
            +
                  #   instead just iterate on the NestedResource itself.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # @param filters [Hash] Parameters to use
         
     | 
| 
      
 10 
     | 
    
         
            +
                  # @return [Clever::APIOperations::ResultList] list of results
         
     | 
| 
      
 11 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   # Without any overriding
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #   district = Clever::Districts.retrieve id
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   district.schools.find(starting_after: lower_bound).each do |school|
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #     puts school.name
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  #
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #   # With overriding
         
     | 
| 
      
 19 
     | 
    
         
            +
                  #   district = Clever::Districts.retrieve id
         
     | 
| 
      
 20 
     | 
    
         
            +
                  #   schools = district.schools(starting_after: lower_bound)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #   # The above filter has been overridden for the query below!
         
     | 
| 
      
 22 
     | 
    
         
            +
                  #   schools.find(starting_after: even_lower_bound).each do |school|
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #     puts school.name
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #   end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def find(filters = {})
         
     | 
| 
      
 26 
     | 
    
         
            +
                    filters = @filters.merge filters
         
     | 
| 
      
 27 
     | 
    
         
            +
                    Clever::APIOperations::PageList.new(@uri, filters).to_results_list
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  # Request the number of elements in a nested list from the API
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # @note This does not count a data structure in memory; it runs an HTTP query!
         
     | 
| 
      
 32 
     | 
    
         
            +
                  # @api public
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # @param filters [Hash] Parameters to use
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # @return [Integer] Results
         
     | 
| 
      
 35 
     | 
    
         
            +
                  # @example
         
     | 
| 
      
 36 
     | 
    
         
            +
                  #   district = Clever::Districts.retrieve id
         
     | 
| 
      
 37 
     | 
    
         
            +
                  #   num_schools_in_district = district.schools.count
         
     | 
| 
      
 38 
     | 
    
         
            +
                  def count(filters = {})
         
     | 
| 
      
 39 
     | 
    
         
            +
                    filters = @filters.merge filters
         
     | 
| 
      
 40 
     | 
    
         
            +
                    filters[:count] = true
         
     | 
| 
      
 41 
     | 
    
         
            +
                    response = Clever.request :get, @uri, filters
         
     | 
| 
      
 42 
     | 
    
         
            +
                    response[:count]
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,6 +1,45 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Clever
         
     | 
| 
       2 
2 
     | 
    
         
             
              # Superclass of API resources in the Clever API
         
     | 
| 
       3 
3 
     | 
    
         
             
              class APIResource < CleverObject
         
     | 
| 
      
 4 
     | 
    
         
            +
                @resources = []
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # Get valid API resources
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 9 
     | 
    
         
            +
                  # @return [Array] List of valid API resource classes
         
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_reader :resources
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # Get a list of nested resources in the Clever API for this resource
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # @return [Array] List of resources nested under this resource
         
     | 
| 
      
 15 
     | 
    
         
            +
                  attr_reader :linked_resources
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                # Registers valid API resources
         
     | 
| 
      
 19 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 20 
     | 
    
         
            +
                # @return [Object]
         
     | 
| 
      
 21 
     | 
    
         
            +
                def self.inherited(child_class)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @resources << child_class
         
     | 
| 
      
 23 
     | 
    
         
            +
                  super
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                # Get a canonical name for a resource
         
     | 
| 
      
 27 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 28 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 29 
     | 
    
         
            +
                def self.shortname
         
     | 
| 
      
 30 
     | 
    
         
            +
                  name.split('::')[-1].downcase.singularize
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # Convert the name of a resource to its APIResource subclass
         
     | 
| 
      
 34 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 35 
     | 
    
         
            +
                # @return [APIResource]
         
     | 
| 
      
 36 
     | 
    
         
            +
                def self.named(name)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  name = name.to_s.downcase.singularize
         
     | 
| 
      
 38 
     | 
    
         
            +
                  matching = resources.select { |res| res.shortname == name }
         
     | 
| 
      
 39 
     | 
    
         
            +
                  return nil if matching.empty?
         
     | 
| 
      
 40 
     | 
    
         
            +
                  matching.first
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       4 
43 
     | 
    
         
             
                # Get URL for a resource
         
     | 
| 
       5 
44 
     | 
    
         
             
                # @api private
         
     | 
| 
       6 
45 
     | 
    
         
             
                # @return [String] url to query for a resource
         
     | 
| 
         @@ -9,8 +48,7 @@ module Clever 
     | 
|
| 
       9 
48 
     | 
    
         
             
                    fail NotImplementedError, 'APIResource is an abstract class. You should perform actions '\
         
     | 
| 
       10 
49 
     | 
    
         
             
                      'on its subclasses (School, Student, etc.)'
         
     | 
| 
       11 
50 
     | 
    
         
             
                  end
         
     | 
| 
       12 
     | 
    
         
            -
                  shortname 
     | 
| 
       13 
     | 
    
         
            -
                  "v1.1/#{CGI.escape shortname.downcase}s"
         
     | 
| 
      
 51 
     | 
    
         
            +
                  "v1.1/#{CGI.escape shortname.pluralize}"
         
     | 
| 
       14 
52 
     | 
    
         
             
                end
         
     | 
| 
       15 
53 
     | 
    
         | 
| 
       16 
54 
     | 
    
         
             
                # Get URL for an instance of a resource
         
     | 
| 
         @@ -32,16 +70,17 @@ module Clever 
     | 
|
| 
       32 
70 
     | 
    
         
             
                def refresh
         
     | 
| 
       33 
71 
     | 
    
         
             
                  response = Clever.request :get, url
         
     | 
| 
       34 
72 
     | 
    
         
             
                  refresh_from response[:data]
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  @links = response[:links].map do
         
     | 
| 
      
 75 
     | 
    
         
            +
                    |link| { :"#{link[:rel]}" => link[:uri] }
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end.reduce({}, :merge)
         
     | 
| 
       35 
77 
     | 
    
         
             
                  self
         
     | 
| 
       36 
78 
     | 
    
         
             
                end
         
     | 
| 
       37 
79 
     | 
    
         | 
| 
       38 
80 
     | 
    
         
             
                # Get hypermedia links for this resource instance
         
     | 
| 
       39 
81 
     | 
    
         
             
                # @api private
         
     | 
| 
       40 
82 
     | 
    
         
             
                # @return [Array] list of links for this resource instance
         
     | 
| 
       41 
     | 
    
         
            -
                 
     | 
| 
       42 
     | 
    
         
            -
                  response = Clever.request :get, url
         
     | 
| 
       43 
     | 
    
         
            -
                  response[:links]
         
     | 
| 
       44 
     | 
    
         
            -
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
                attr_reader :links
         
     | 
| 
       45 
84 
     | 
    
         | 
| 
       46 
85 
     | 
    
         
             
                # Get an instance of a resource
         
     | 
| 
       47 
86 
     | 
    
         
             
                # @api public
         
     | 
| 
         @@ -56,33 +95,34 @@ module Clever 
     | 
|
| 
       56 
95 
     | 
    
         
             
                  instance
         
     | 
| 
       57 
96 
     | 
    
         
             
                end
         
     | 
| 
       58 
97 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
                #  
     | 
| 
      
 98 
     | 
    
         
            +
                # Get the URI for a hypermedia link
         
     | 
| 
       60 
99 
     | 
    
         
             
                # @api private
         
     | 
| 
       61 
     | 
    
         
            -
                # @return [ 
     | 
| 
       62 
     | 
    
         
            -
                def  
     | 
| 
       63 
     | 
    
         
            -
                   
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                class << self
         
     | 
| 
       67 
     | 
    
         
            -
                  # Get a list of nested resources in the Clever API for this resource
         
     | 
| 
       68 
     | 
    
         
            -
                  # @api private
         
     | 
| 
       69 
     | 
    
         
            -
                  # @return [Array] List of resources nested under this resource
         
     | 
| 
       70 
     | 
    
         
            -
                  attr_reader :linked_resources
         
     | 
| 
      
 100 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 101 
     | 
    
         
            +
                def get_link_uri(resource_type)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  refresh if links.nil?
         
     | 
| 
      
 103 
     | 
    
         
            +
                  links[resource_type.to_sym]
         
     | 
| 
       71 
104 
     | 
    
         
             
                end
         
     | 
| 
       72 
105 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
                #  
     | 
| 
       74 
     | 
    
         
            -
                # @ 
     | 
| 
       75 
     | 
    
         
            -
                # @ 
     | 
| 
       76 
     | 
    
         
            -
                # @return [ 
     | 
| 
       77 
     | 
    
         
            -
                # @example
         
     | 
| 
       78 
     | 
    
         
            -
                #   Clever::District.new '531fabe082d522cds8e22'
         
     | 
| 
      
 106 
     | 
    
         
            +
                # Construct an APIResource. Generates methods for nested resources
         
     | 
| 
      
 107 
     | 
    
         
            +
                # @abstract
         
     | 
| 
      
 108 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 109 
     | 
    
         
            +
                # @return [APIResource]
         
     | 
| 
       79 
110 
     | 
    
         
             
                def initialize(id)
         
     | 
| 
       80 
111 
     | 
    
         
             
                  super id
         
     | 
| 
      
 112 
     | 
    
         
            +
                  return if self.class.linked_resources.nil?
         
     | 
| 
       81 
113 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                   
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                       
     | 
| 
      
 114 
     | 
    
         
            +
                  self.class.linked_resources.each do |resource|
         
     | 
| 
      
 115 
     | 
    
         
            +
                    if Clever::Util.singular? resource.to_s
         
     | 
| 
      
 116 
     | 
    
         
            +
                      # Get single resource
         
     | 
| 
      
 117 
     | 
    
         
            +
                      self.class.send :define_method, resource do
         
     | 
| 
      
 118 
     | 
    
         
            +
                        response = Clever.request :get, get_link_uri(resource)
         
     | 
| 
      
 119 
     | 
    
         
            +
                        return Util.convert_to_clever_object response
         
     | 
| 
      
 120 
     | 
    
         
            +
                      end
         
     | 
| 
      
 121 
     | 
    
         
            +
                    else
         
     | 
| 
      
 122 
     | 
    
         
            +
                      # Get list of nested resources
         
     | 
| 
      
 123 
     | 
    
         
            +
                      self.class.send :define_method, resource do |filters = {}|
         
     | 
| 
      
 124 
     | 
    
         
            +
                        Clever::NestedResource.new get_link_uri(resource), filters
         
     | 
| 
      
 125 
     | 
    
         
            +
                      end
         
     | 
| 
       86 
126 
     | 
    
         
             
                    end
         
     | 
| 
       87 
127 
     | 
    
         
             
                  end
         
     | 
| 
       88 
128 
     | 
    
         
             
                end
         
     | 
| 
         @@ -10,9 +10,11 @@ module Clever 
     | 
|
| 
       10 
10 
     | 
    
         
             
                # The default :id method is deprecated and isn't useful to us
         
     | 
| 
       11 
11 
     | 
    
         
             
                undef :id if method_defined? :id
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
                # Create  
     | 
| 
      
 13 
     | 
    
         
            +
                # Create an instance of CleverObject by id
         
     | 
| 
      
 14 
     | 
    
         
            +
                # @abstract
         
     | 
| 
       14 
15 
     | 
    
         
             
                # @api private
         
     | 
| 
       15 
     | 
    
         
            -
                # @ 
     | 
| 
      
 16 
     | 
    
         
            +
                # @param id [String, Hash] id, or values to instantiate from
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @return [CleverObject] resource instance
         
     | 
| 
       16 
18 
     | 
    
         
             
                def initialize(id = nil)
         
     | 
| 
       17 
19 
     | 
    
         
             
                  @values = {}
         
     | 
| 
       18 
20 
     | 
    
         
             
                  @values[:id] = id if id
         
     | 
| 
         @@ -194,9 +196,13 @@ module Clever 
     | 
|
| 
       194 
196 
     | 
    
         
             
                # @api private
         
     | 
| 
       195 
197 
     | 
    
         
             
                # @return [Object]
         
     | 
| 
       196 
198 
     | 
    
         
             
                def add_accessors(keys)
         
     | 
| 
      
 199 
     | 
    
         
            +
                  obj = self
         
     | 
| 
       197 
200 
     | 
    
         
             
                  metaclass.instance_eval do
         
     | 
| 
       198 
201 
     | 
    
         
             
                    keys.each do |k|
         
     | 
| 
       199 
202 
     | 
    
         
             
                      next if @@permanent_attributes.include? k
         
     | 
| 
      
 203 
     | 
    
         
            +
                      unless obj.class.linked_resources.nil?
         
     | 
| 
      
 204 
     | 
    
         
            +
                        next if obj.class.linked_resources.include? k
         
     | 
| 
      
 205 
     | 
    
         
            +
                      end
         
     | 
| 
       200 
206 
     | 
    
         
             
                      k_eq = :"#{k}="
         
     | 
| 
       201 
207 
     | 
    
         
             
                      define_method(k) { @values[k] }
         
     | 
| 
       202 
208 
     | 
    
         
             
                      define_method(k_eq) { |v| @values[k] = v }
         
     | 
    
        data/lib/clever-ruby/district.rb
    CHANGED
    
    | 
         @@ -4,6 +4,30 @@ module Clever 
     | 
|
| 
       4 
4 
     | 
    
         
             
                include Clever::APIOperations::List
         
     | 
| 
       5 
5 
     | 
    
         
             
                @linked_resources = [:schools, :teachers, :sections, :students, :events]
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
      
 7 
     | 
    
         
            +
                # Get admins for the current district
         
     | 
| 
      
 8 
     | 
    
         
            +
                # @todo This is not implemented!
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @raise [NotImplementedError]
         
     | 
| 
      
 11 
     | 
    
         
            +
                # @return [Object]
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 13 
     | 
    
         
            +
                #   district = district.retrieve id
         
     | 
| 
      
 14 
     | 
    
         
            +
                #   admins = district.admins
         
     | 
| 
      
 15 
     | 
    
         
            +
                def admins
         
     | 
| 
      
 16 
     | 
    
         
            +
                  fail NotImplementedError, 'admins nested resource not yet implemented.'
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                # Get status of the current district
         
     | 
| 
      
 20 
     | 
    
         
            +
                # @todo This is not implemented!
         
     | 
| 
      
 21 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 22 
     | 
    
         
            +
                # @raise [NotImplementedError]
         
     | 
| 
      
 23 
     | 
    
         
            +
                # @return [Object]
         
     | 
| 
      
 24 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 25 
     | 
    
         
            +
                #   district = district.retrieve id
         
     | 
| 
      
 26 
     | 
    
         
            +
                #   puts district.status
         
     | 
| 
      
 27 
     | 
    
         
            +
                def status
         
     | 
| 
      
 28 
     | 
    
         
            +
                  fail NotImplementedError, 'status nested resource not yet implemented.'
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
       7 
31 
     | 
    
         
             
                # @see Clever::CleverObject.optional_attributes
         
     | 
| 
       8 
32 
     | 
    
         
             
                # @api private
         
     | 
| 
       9 
33 
     | 
    
         
             
                # @return [Array]
         
     | 
| 
         @@ -15,18 +39,8 @@ module Clever 
     | 
|
| 
       15 
39 
     | 
    
         
             
                # TODO: remove
         
     | 
| 
       16 
40 
     | 
    
         
             
                [:school_pages, :teacher_pages, :section_pages, :student_pages, :event_pages].each do |name|
         
     | 
| 
       17 
41 
     | 
    
         
             
                  define_method(name) do |filters = {}|
         
     | 
| 
       18 
     | 
    
         
            -
                    Clever::APIOperations::PageList.new  
     | 
| 
      
 42 
     | 
    
         
            +
                    Clever::APIOperations::PageList.new get_link_uri(name.to_s.gsub('_page', '')), filters
         
     | 
| 
       19 
43 
     | 
    
         
             
                  end
         
     | 
| 
       20 
44 
     | 
    
         
             
                end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                private
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                # Get the URI for a hypermedia link
         
     | 
| 
       25 
     | 
    
         
            -
                # @api private
         
     | 
| 
       26 
     | 
    
         
            -
                # @return [String]
         
     | 
| 
       27 
     | 
    
         
            -
                def get_uri(resource_type)
         
     | 
| 
       28 
     | 
    
         
            -
                  refresh
         
     | 
| 
       29 
     | 
    
         
            -
                  links.find { |link| link[:rel] == resource_type }[:uri]
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
45 
     | 
    
         
             
              end
         
     | 
| 
       32 
46 
     | 
    
         
             
            end
         
     | 
    
        data/lib/clever-ruby/event.rb
    CHANGED
    
    
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Clever
         
     | 
| 
      
 2 
     | 
    
         
            +
              # An interface for querying nested resources
         
     | 
| 
      
 3 
     | 
    
         
            +
              class NestedResource
         
     | 
| 
      
 4 
     | 
    
         
            +
                include Clever::APIOperations::NestedList
         
     | 
| 
      
 5 
     | 
    
         
            +
                include Enumerable
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # Create a nested resource
         
     | 
| 
      
 8 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @return [Clever::APIOperations::NestedList]
         
     | 
| 
      
 10 
     | 
    
         
            +
                def initialize(uri, filters = {})
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @uri = uri
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @filters = filters
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @results_list = Clever::APIOperations::PageList.new(uri, filters).to_results_list
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # Query and iterate over results for the params provided during initialization
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 18 
     | 
    
         
            +
                # @return [Clever::APIOperations::NestedResource] self
         
     | 
| 
      
 19 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 20 
     | 
    
         
            +
                #   district = Clever::Districts.retrieve id
         
     | 
| 
      
 21 
     | 
    
         
            +
                #   district.schools.each { |school| puts school.name }
         
     | 
| 
      
 22 
     | 
    
         
            +
                def each(&blk)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @results_list.each(&blk)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  self
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                # Query for all results and count them
         
     | 
| 
      
 28 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 29 
     | 
    
         
            +
                # @note This queries for the actual elements! If you wish to just do a
         
     | 
| 
      
 30 
     | 
    
         
            +
                #   count query, use the count method
         
     | 
| 
      
 31 
     | 
    
         
            +
                # @return [Integer]
         
     | 
| 
      
 32 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 33 
     | 
    
         
            +
                #   district = Clever::District.retrieve id
         
     | 
| 
      
 34 
     | 
    
         
            +
                #   num_schools_for_district = district.schools.length
         
     | 
| 
      
 35 
     | 
    
         
            +
                def length
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @results_list.count
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
                alias_method :size, :length
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/clever-ruby/school.rb
    CHANGED
    
    | 
         @@ -2,7 +2,7 @@ module Clever 
     | 
|
| 
       2 
2 
     | 
    
         
             
              # School resource
         
     | 
| 
       3 
3 
     | 
    
         
             
              class School < APIResource
         
     | 
| 
       4 
4 
     | 
    
         
             
                include Clever::APIOperations::List
         
     | 
| 
       5 
     | 
    
         
            -
                @linked_resources = [: 
     | 
| 
      
 5 
     | 
    
         
            +
                @linked_resources = [:students, :district, :sections, :teachers, :events]
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                # Optional attributes
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @see Clever::CleverObject.optional_attributes
         
     | 
    
        data/lib/clever-ruby/section.rb
    CHANGED
    
    | 
         @@ -2,7 +2,7 @@ module Clever 
     | 
|
| 
       2 
2 
     | 
    
         
             
              # Section resource
         
     | 
| 
       3 
3 
     | 
    
         
             
              class Section < APIResource
         
     | 
| 
       4 
4 
     | 
    
         
             
                include Clever::APIOperations::List
         
     | 
| 
       5 
     | 
    
         
            -
                @linked_resources = [: 
     | 
| 
      
 5 
     | 
    
         
            +
                @linked_resources = [:school, :district, :students, :teacher, :events]
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                # Optional attributes
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @see Clever::CleverObject.optional_attributes
         
     | 
    
        data/lib/clever-ruby/student.rb
    CHANGED
    
    | 
         @@ -2,7 +2,19 @@ module Clever 
     | 
|
| 
       2 
2 
     | 
    
         
             
              # Student resource
         
     | 
| 
       3 
3 
     | 
    
         
             
              class Student < APIResource
         
     | 
| 
       4 
4 
     | 
    
         
             
                include Clever::APIOperations::List
         
     | 
| 
       5 
     | 
    
         
            -
                @linked_resources = [: 
     | 
| 
      
 5 
     | 
    
         
            +
                @linked_resources = [:school, :district, :sections, :teachers, :events]
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                # Get contacts for the current student
         
     | 
| 
      
 8 
     | 
    
         
            +
                # @todo This is not implemented!
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @api public
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @raise [NotImplementedError]
         
     | 
| 
      
 11 
     | 
    
         
            +
                # @return [Object]
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 13 
     | 
    
         
            +
                #   student = student.retrieve id
         
     | 
| 
      
 14 
     | 
    
         
            +
                #   contacts = student.admins
         
     | 
| 
      
 15 
     | 
    
         
            +
                def contacts
         
     | 
| 
      
 16 
     | 
    
         
            +
                  fail NotImplementedError, 'contacts nested resource not implemented yet.'
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
       6 
18 
     | 
    
         | 
| 
       7 
19 
     | 
    
         
             
                # Optional attributes
         
     | 
| 
       8 
20 
     | 
    
         
             
                # @see Clever::CleverObject.optional_attributes
         
     | 
    
        data/lib/clever-ruby/teacher.rb
    CHANGED
    
    | 
         @@ -2,7 +2,7 @@ module Clever 
     | 
|
| 
       2 
2 
     | 
    
         
             
              # Teacher resource
         
     | 
| 
       3 
3 
     | 
    
         
             
              class Teacher < APIResource
         
     | 
| 
       4 
4 
     | 
    
         
             
                include Clever::APIOperations::List
         
     | 
| 
       5 
     | 
    
         
            -
                @linked_resources = [: 
     | 
| 
      
 5 
     | 
    
         
            +
                @linked_resources = [:school, :district, :students, :sections, :events]
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
                # Optional attributes
         
     | 
| 
       8 
8 
     | 
    
         
             
                # @see Clever::CleverObject.optional_attributes
         
     | 
    
        data/lib/clever-ruby/util.rb
    CHANGED
    
    | 
         @@ -1,6 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module Clever
         
     | 
| 
       2 
2 
     | 
    
         
             
              # Library helper methods
         
     | 
| 
       3 
3 
     | 
    
         
             
              module Util
         
     | 
| 
      
 4 
     | 
    
         
            +
                # Check if a given word is singular
         
     | 
| 
      
 5 
     | 
    
         
            +
                # @api private
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @param word [String] Word to check
         
     | 
| 
      
 7 
     | 
    
         
            +
                # @return [Boolean] False if plural, true if singular
         
     | 
| 
      
 8 
     | 
    
         
            +
                def self.singular?(word)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  word.singularize == word
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       4 
12 
     | 
    
         
             
                # Check if a given ID is a valid format (MongoDB BSON ObjectID)
         
     | 
| 
       5 
13 
     | 
    
         
             
                # @api private
         
     | 
| 
       6 
14 
     | 
    
         
             
                # @param id [String] ID to check
         
     | 
| 
         @@ -27,21 +35,6 @@ module Clever 
     | 
|
| 
       27 
35 
     | 
    
         
             
                  end
         
     | 
| 
       28 
36 
     | 
    
         
             
                end
         
     | 
| 
       29 
37 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                # Convert the name of a resource to its APIResource class
         
     | 
| 
       31 
     | 
    
         
            -
                # @api private
         
     | 
| 
       32 
     | 
    
         
            -
                # @return [APIResource]
         
     | 
| 
       33 
     | 
    
         
            -
                def self.types_to_clever_class(type)
         
     | 
| 
       34 
     | 
    
         
            -
                  types = {
         
     | 
| 
       35 
     | 
    
         
            -
                    'students'  => Student,
         
     | 
| 
       36 
     | 
    
         
            -
                    'sections'  => Section,
         
     | 
| 
       37 
     | 
    
         
            -
                    'teachers'  => Teacher,
         
     | 
| 
       38 
     | 
    
         
            -
                    'districts' => District,
         
     | 
| 
       39 
     | 
    
         
            -
                    'schools'   => School,
         
     | 
| 
       40 
     | 
    
         
            -
                    'events'    => Event
         
     | 
| 
       41 
     | 
    
         
            -
                  }
         
     | 
| 
       42 
     | 
    
         
            -
                  types.fetch type
         
     | 
| 
       43 
     | 
    
         
            -
                end
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
38 
     | 
    
         
             
                # Convert an object containing data from Clever into a CleverObject
         
     | 
| 
       46 
39 
     | 
    
         
             
                # @api private
         
     | 
| 
       47 
40 
     | 
    
         
             
                # @return [CleverObject]
         
     | 
| 
         @@ -52,8 +45,14 @@ module Clever 
     | 
|
| 
       52 
45 
     | 
    
         
             
                  when Hash
         
     | 
| 
       53 
46 
     | 
    
         
             
                    # Try converting to a known object class. If none available, fall back to generic
         
     | 
| 
       54 
47 
     | 
    
         
             
                    # APIResource.
         
     | 
| 
       55 
     | 
    
         
            -
                     
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
                    if resp.key? :uri
         
     | 
| 
      
 49 
     | 
    
         
            +
                      uri = resp[:uri]
         
     | 
| 
      
 50 
     | 
    
         
            +
                    else
         
     | 
| 
      
 51 
     | 
    
         
            +
                      uri = resp[:links].select { |l| l[:rel] == 'self' }[0][:uri]
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    klass_name = %r{/v1.1/([a-z]+)/\S+$}.match(uri)[1]
         
     | 
| 
      
 55 
     | 
    
         
            +
                    klass = APIResource.named klass_name if klass_name
         
     | 
| 
       57 
56 
     | 
    
         
             
                    klass ||= CleverObject
         
     | 
| 
       58 
57 
     | 
    
         
             
                    klass.construct_from resp[:data]
         
     | 
| 
       59 
58 
     | 
    
         
             
                  else
         
     |