get assignments and submissions from all shards

fixes CNVS-4959

(note that this does not cover the cross-shard links
from these assignments working correctly; that is a
separate issue)

test plan:
 * enroll a user in courses in multiple shards
 * assignments from all courses should show up in
   /assignments regardless of current shard

Change-Id: Ic46711a31ddc573f124cad3ed2bc5abefd4646a9
Reviewed-on: https://gerrit.instructure.com/19234
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Clare Strong <clare@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2013-04-01 12:55:32 -06:00
parent b993954788
commit 4ffcfe0721
4 changed files with 59 additions and 21 deletions

View File

@ -446,8 +446,8 @@ class ApplicationController < ActionController::Base
# we already know the user can read these courses and groups, so skip
# the grants_right? check to avoid querying for the various memberships
# again.
courses = @context.current_enrollments.select { |e| e.state_based_on_date == :active }.map(&:course).uniq
groups = include_groups ? @context.current_groups : []
courses = @context.current_enrollments.with_each_shard.select { |e| e.state_based_on_date == :active }.map(&:course).uniq
groups = include_groups ? @context.current_groups.with_each_shard : []
if only_contexts.present?
# find only those courses and groups passed in the only_contexts
# parameter, but still scoped by user so we know they have rights to
@ -455,7 +455,7 @@ class ApplicationController < ActionController::Base
course_ids = only_contexts.select { |c| c.first == "Course" }.map(&:last)
courses = course_ids.empty? ? [] : courses.select { |c| course_ids.include?(c.id) }
group_ids = only_contexts.select { |c| c.first == "Group" }.map(&:last)
groups = group_ids.empty? ? [] : groups.find_all_by_id(group_ids) if include_groups
groups = group_ids.empty? ? [] : groups.select { |g| group_ids.include?(g.id) } if include_groups
end
@contexts.concat courses
@contexts.concat groups
@ -509,15 +509,23 @@ class ApplicationController < ActionController::Base
@groups = @courses.first.assignment_groups.active.includes(:active_assignments)
@assignments = @groups.map(&:active_assignments).flatten
else
@groups = AssignmentGroup.for_context_codes(@context_codes).active
@assignments = Assignment.active.for_course(@courses.map(&:id))
assignments_and_groups = Shard.partition_by_shard(@courses) do |courses|
[[Assignment.active.for_course(courses).all,
AssignmentGroup.active.for_course(courses).order(:position).all]]
end
@assignments = assignments_and_groups.map(&:first).flatten
@groups = assignments_and_groups.map(&:last).flatten
end
@assignment_groups = @groups
@courses.each { |course| log_course(course) }
@submissions = @current_user.try(:submissions).to_a
@submissions.each{ |s| s.mute if s.muted_assignment? }
if @current_user
@submissions = @current_user.submissions.with_each_shard
@submissions.each{ |s| s.mute if s.muted_assignment? }
else
@submissions = []
end
@assignments.map! {|a| a.overridden_for(@current_user)}
sorted = SortsAssignments.by_due_date({

View File

@ -126,6 +126,7 @@ class AssignmentGroup < ActiveRecord::Base
scope :active, where("assignment_groups.workflow_state<>'deleted'")
scope :before, lambda { |date| where("assignment_groups.created_at<?", date) }
scope :for_context_codes, lambda { |codes| active.where(:context_code => codes).order(:position) }
scope :for_course, lambda { |course| where(:context_id => course, :context_type => 'Course') }
def group_weight_changed
@group_weight_changed = self.group_weight_changed?

View File

@ -864,20 +864,25 @@ class Course < ActiveRecord::Base
def self.require_assignment_groups(contexts)
courses = contexts.select{|c| c.is_a?(Course) }
hash = {}
courses.each{|c| hash[c.id] = {:found => false, :course => c} }
groups = AssignmentGroup.select("id, context_id, context_type").where(:context_type => "Course", :context_id => courses)
groups.each{|c| hash[c.context_id][:found] = true }
hash.select{|id, obj| !obj[:found] }.each{|id, obj| obj[:course].require_assignment_group rescue nil }
groups = Shard.partition_by_shard(courses) do |shard_courses|
AssignmentGroup.select("id, context_id, context_type").where(:context_type => "Course", :context_id => shard_courses)
end.index_by(&:context_id)
courses.each do |course|
if !groups[course.id]
course.require_assignment_group rescue nil
end
end
end
def require_assignment_group
has_group = Rails.cache.read(['has_assignment_group', self].cache_key)
return if has_group && Rails.env.production?
if self.assignment_groups.active.empty?
self.assignment_groups.create(:name => t('#assignment_group.default_name', "Assignments"))
shard.activate do
has_group = Rails.cache.read(['has_assignment_group', self].cache_key)
return if has_group && Rails.env.production?
if self.assignment_groups.active.empty?
self.assignment_groups.create(:name => t('#assignment_group.default_name', "Assignments"))
end
Rails.cache.write(['has_assignment_group', self].cache_key, true)
end
Rails.cache.write(['has_assignment_group', self].cache_key, true)
end
def self.create_unique(uuid=nil, account_id=nil, root_account_id=nil)

View File

@ -16,18 +16,20 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
require File.expand_path(File.dirname(__FILE__) + '/../sharding_spec_helper')
describe AssignmentsController do
# it "should use AssignmentsController" do
# controller.should be_an_instance_of(AssignmentsController)
# end
def course_assignment
@group = @course.assignment_groups.create(:name => "some group")
@assignment = @course.assignments.create(:title => "some assignment", :assignment_group => @group)
def course_assignment(course = nil)
course ||= @course
@group = course.assignment_groups.create(:name => "some group")
@assignment = course.assignments.create(:title => "some assignment", :assignment_group => @group)
@assignment.assignment_group.should eql(@group)
@group.assignments.should be_include(@assignment)
@assignment
end
describe "GET 'index'" do
@ -81,6 +83,28 @@ describe AssignmentsController do
assigns[:assignment_groups].should_not be_empty
assigns[:assignment_groups][0].name.should eql("Assignments")
end
context "sharding" do
specs_require_sharding
it "should show assignments for all shards" do
course_with_student_logged_in(:active_all => true)
@assignment1 = course_assignment
@shard2.activate do
account = Account.create!
course2 = account.courses.create!
course2.offer!
@assignment2 = course_assignment(course2)
course2.enroll_student(@user).accept!
end
get 'index'
assigns[:assignments].length.should == 2
assigns[:assignments].should be_include(@assignment1)
assigns[:assignments].should be_include(@assignment2)
end
end
end
describe "GET 'show'" do