diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 44103cd2e9b..b1372125199 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -24,7 +24,6 @@ class AccountsController < ApplicationController include Api::V1::Account # @API - # # List accounts that the current user can view or manage. Typically, # students and even teachers will get an empty list in response, only # account admins can view the accounts that they are in. @@ -44,7 +43,6 @@ class AccountsController < ApplicationController end # @API - # # Retrieve information on an individual account, given by id or sis # sis_account_id. def show @@ -61,6 +59,26 @@ class AccountsController < ApplicationController end end + include Api::V1::Course + + # @API + # Retrieve the list of active (non-deleted) courses in this account. + # + # @argument hide_enrollmentless_courses [optional] If set, only return courses that have at least one enrollment. + # + # @example_response + # [ { 'id': 1, 'name': 'first course', 'course_code': 'first', 'sis_course_id': 'first-sis' }, + # { 'id': 2, 'name': 'second course', 'course_code': 'second', 'sis_course_id': null } ] + def courses_api + if authorized_action(@account, @current_user, :read) + @courses = @account.associated_courses.active + @courses = @courses.with_enrollments if params[:hide_enrollmentless_courses] + @courses = @courses.paginate(:order => :id, :page => params[:page], :per_page => params[:per_page] || 10) + Api.set_pagination_headers!(@courses, response, api_v1_account_courses_path) + render :json => @courses.map { |c| course_json(c, [], nil) } + end + end + def update if authorized_action(@account, @current_user, :manage_account_settings) respond_to do |format| diff --git a/app/models/account.rb b/app/models/account.rb index d17d41d2c2b..a40467e4a1d 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -244,14 +244,11 @@ class Account < ActiveRecord::Base def fast_course_base(opts) columns = "courses.id, courses.name, courses.section, courses.workflow_state, courses.course_code, courses.sis_source_id" - conditions = [] - if opts[:hide_enrollmentless_courses] - conditions = ["exists (#{Enrollment.active.send(:construct_finder_sql, {:select => "1", :conditions => ["enrollments.course_id = courses.id"]})})"] - end associated_courses = self.associated_courses.active + associated_courses = associated_courses.with_enrollments if opts[:hide_enrollmentless_courses] associated_courses = associated_courses.for_term(opts[:term]) if opts[:term].present? associated_courses = yield associated_courses if block_given? - associated_courses.limit(opts[:limit]).active_first.find(:all, :select => columns, :group => columns, :conditions => conditions) + associated_courses.limit(opts[:limit]).active_first.find(:all, :select => columns, :group => columns) end def fast_all_courses(opts={}) diff --git a/app/models/course.rb b/app/models/course.rb index 5d853060a7b..95a6de488e2 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -429,6 +429,10 @@ class Course < ActiveRecord::Base } named_scope :not_deleted, {:conditions => ['workflow_state != ?', 'deleted']} + named_scope :with_enrollments, lambda { + { :conditions => ["exists (#{Enrollment.active.send(:construct_finder_sql, {:select => "1", :conditions => ["enrollments.course_id = courses.id"]})})"] } + } + set_broadcast_policy do |p| p.dispatch :grade_weight_changed p.to { participating_students } diff --git a/config/routes.rb b/config/routes.rb index a737896eda0..b781cc914b3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -675,6 +675,7 @@ ActionController::Routing::Routes.draw do |map| api.with_options(:controller => :accounts) do |accounts| accounts.get 'accounts', :action => :index, :path_name => 'accounts' accounts.get 'accounts/:id', :action => :show + accounts.get 'accounts/:account_id/courses', :action => :courses_api, :path_name => 'account_courses' end end diff --git a/lib/api/v1/course.rb b/lib/api/v1/course.rb index cbe44b7e00e..4cb9b67a546 100644 --- a/lib/api/v1/course.rb +++ b/lib/api/v1/course.rb @@ -24,8 +24,8 @@ module Api::V1::Course hash = course.as_json( :include_root => false, :only => %w(id name course_code)) hash['sis_course_id'] = course.sis_source_id - hash['enrollments'] = enrollments.map { |e| { :type => e.readable_type.downcase } } - if include_grading && enrollments.any? { |e| e.participating_admin? } + hash['enrollments'] = enrollments.map { |e| { :type => e.readable_type.downcase } } if enrollments + if include_grading && enrollments && enrollments.any? { |e| e.participating_admin? } hash['needs_grading_count'] = course.assignments.active.sum('needs_grading_count') end if include_syllabus diff --git a/spec/apis/v1/accounts_api_spec.rb b/spec/apis/v1/accounts_api_spec.rb index 23bda118fc9..c7a2b1b99eb 100644 --- a/spec/apis/v1/accounts_api_spec.rb +++ b/spec/apis/v1/accounts_api_spec.rb @@ -76,5 +76,53 @@ describe "Accounts API", :type => :integration do 'sis_account_id' => 'sis1', } end + + it "should return courses for an account" do + @me = @user + @c1 = course_model(:name => 'c1', :account => @a1, :root_account => @a1) + @c1.enrollments.delete_all + @c2 = course_model(:name => 'c2', :account => @a2, :root_account => @a1, :sis_source_id => 'sis2') + @user = @me + json = api_call(:get, "/api/v1/accounts/#{@a1.id}/courses", + { :controller => 'accounts', :action => 'courses_api', :account_id => @a1.to_param, :format => 'json' }) + json.should == [ + { + 'id' => @c1.id, + 'name' => 'c1', + 'course_code' => 'c1', + 'sis_course_id' => nil, + }, + { + 'id' => @c2.id, + 'name' => 'c2', + 'course_code' => 'c2', + 'sis_course_id' => 'sis2', + }, + ] + + json = api_call(:get, "/api/v1/accounts/#{@a1.id}/courses", + { :controller => 'accounts', :action => 'courses_api', :account_id => @a1.to_param, :format => 'json' }, + { :hide_enrollmentless_courses => '1' }) + json.should == [ + { + 'id' => @c2.id, + 'name' => 'c2', + 'course_code' => 'c2', + 'sis_course_id' => 'sis2', + }, + ] + + json = api_call(:get, "/api/v1/accounts/#{@a1.id}/courses", + { :controller => 'accounts', :action => 'courses_api', :account_id => @a1.to_param, :format => 'json' }, + { :per_page => 1, :page => 2 }) + json.should == [ + { + 'id' => @c2.id, + 'name' => 'c2', + 'course_code' => 'c2', + 'sis_course_id' => 'sis2', + }, + ] + end end