don't use preload_associations

it's a shim of the rails 2 variety, and breaks in rails 4 in the
common case because the options became a scope

Change-Id: I712a8fed35ee0a9747a13c1495f7d51b8dac6823
Reviewed-on: https://gerrit.instructure.com/41716
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Nick Cloward <ncloward@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2014-09-24 12:39:07 -06:00
parent 5cfaa2c031
commit 1f8028f163
33 changed files with 58 additions and 64 deletions

View File

@ -116,7 +116,7 @@ class AccountsController < ApplicationController
else
@accounts = []
end
Account.send(:preload_associations, @accounts, [:root_account])
ActiveRecord::Associations::Preloader.new(@accounts, :root_account).run
render :json => @accounts.map { |a| account_json(a, @current_user, session, params[:includes] || []) }
end
end
@ -135,7 +135,7 @@ class AccountsController < ApplicationController
js_env(:ACCOUNT_COURSES_PATH => account_courses_path(@account, :format => :json))
load_course_right_side
@courses = @account.fast_all_courses(:term => @term, :limit => @maximum_courses_im_gonna_show, :hide_enrollmentless_courses => @hide_enrollmentless_courses)
Course.send(:preload_associations, @courses, :enrollment_term)
ActiveRecord::Associations::Preloader.new(@courses, :enrollment_term).run
build_course_stats
end
format.json { render :json => account_json(@account, @current_user, session, params[:includes] || []) }
@ -178,7 +178,7 @@ class AccountsController < ApplicationController
@accounts = Api.paginate(@accounts, self, api_v1_sub_accounts_url,
:total_entries => recursive ? nil : @accounts.count)
Account.send(:preload_associations, @accounts, [:root_account, :parent_account])
ActiveRecord::Associations::Preloader.new(@accounts, [:root_account, :parent_account]).run
render :json => @accounts.map { |a| account_json(a, @current_user, session, []) }
end
@ -282,7 +282,7 @@ class AccountsController < ApplicationController
@courses = Api.paginate(@courses, self, api_v1_account_courses_url)
Course.send(:preload_associations, @courses, [:account, :root_account])
ActiveRecord::Associations::Preloader.new(@courses, [:account, :root_account])
render :json => @courses.map { |c| course_json(c, @current_user, session, [], nil) }
end
@ -486,7 +486,7 @@ class AccountsController < ApplicationController
end
load_course_right_side
@account_users = @account.account_users
AccountUser.send(:preload_associations, @account_users, user: :communication_channels)
ActiveRecord::Associations::Preloader.new(@account_users, user: :communication_channels).run
order_hash = {}
@account.available_account_roles.each_with_index do |type, idx|
order_hash[type] = idx

View File

@ -257,7 +257,7 @@ class AppointmentGroupsController < ApplicationController
api_v1_appointment_groups_url(:scope => params[:scope])
)
if params[:include]
AppointmentGroup.send(:preload_associations, groups,
ActiveRecord::Associations::Preloader.new(groups,
[{:appointments =>
[:parent_event,
{:context =>
@ -270,7 +270,7 @@ class AppointmentGroupsController < ApplicationController
[:parent_event,
:context]}]}]},
{:appointment_group_contexts => :context},
:appointment_group_sub_contexts])
:appointment_group_sub_contexts]).run
end
render :json => groups.map{ |group| appointment_group_json(group, @current_user, session, :include => params[:include]) }
end

View File

@ -118,7 +118,7 @@ class AssignmentGroupsController < ApplicationController
# aliased table names the conditons on has_many :context_module_tags will break
if params[:include].include? "module_ids"
module_includes = [:context_module_tags,{:discussion_topic => :context_module_tags},{:quiz => :context_module_tags}]
Assignment.send(:preload_associations, all_visible_assignments, module_includes)
ActiveRecord::Associations::Preloader.new(all_visible_assignments, module_includes).run
end
assignment_descriptions = all_visible_assignments.map(&:description)

View File

@ -548,7 +548,7 @@ class AssignmentsApiController < ApplicationController
override_param = params[:override_assignment_dates] || true
override_dates = value_to_boolean(override_param)
if override_dates
Assignment.send(:preload_associations, assignments, :assignment_overrides)
ActiveRecord::Associations::Preloader.new(assignments, :assignment_overrides).run
assignments.select{ |a| a.assignment_overrides.size == 0 }.
each { |a| a.has_no_overrides = true }
end

View File

@ -304,7 +304,7 @@ class CalendarEventsApiController < ApplicationController
scope = @type == :assignment ? assignment_scope : calendar_event_scope
events = Api.paginate(scope, self, api_v1_calendar_events_url)
CalendarEvent.send(:preload_associations, events, :child_events) if @type == :event
ActiveRecord::Associations::Preloader.new(events, :child_events).run if @type == :event
events = apply_assignment_overrides(events) if @type == :assignment
if @errors.empty?

View File

@ -223,7 +223,7 @@ class ContextModuleItemsApiController < ApplicationController
def index
if authorized_action(@context, @current_user, :read)
mod = @context.modules_visible_to(@student || @current_user).find(params[:module_id])
ContextModule.send(:preload_associations, mod, {:content_tags => :content})
ActiveRecord::Associations::Preloader.new(mod, content_tags: :content).run
route = polymorphic_url([:api_v1, @context, mod, :items])
scope = mod.content_tags_visible_to(@student || @current_user)
scope = ContentTag.search_by_attribute(scope, :title, params[:search_term])

View File

@ -358,7 +358,7 @@ class ContextModulesApiController < ApplicationController
scope = ContextModule.search_by_attribute(scope, :name, params[:search_term]) unless includes.include?('items')
modules = Api.paginate(scope, self, route)
ContextModule.send(:preload_associations, modules, {:content_tags => :content}) if includes.include?('items')
ActiveRecord::Associations::Preloader.new(modules, content_tags: :content) if includes.include?('items')
if @student
modules_and_progressions = modules.map { |m| [m, m.evaluate_for(@student)] }
@ -418,7 +418,7 @@ class ContextModulesApiController < ApplicationController
if authorized_action(@context, @current_user, :read)
mod = @context.modules_visible_to(@student || @current_user).find(params[:id])
includes = Array(params[:include])
ContextModule.send(:preload_associations, mod, {:content_tags => :content}) if includes.include?('items')
ActiveRecord::Associations::Preloader.new(mod, content_tags: :content).run if includes.include?('items')
prog = @student ? mod.evaluate_for(@student) : nil
render :json => module_json(mod, @student || @current_user, session, prog, includes)
end

View File

@ -40,7 +40,7 @@ class ContextModulesController < ApplicationController
load_modules
if @context.grants_right?(@current_user, session, :participate_as_student)
return unless tab_enabled?(@context.class::TAB_MODULES)
ContextModule.send(:preload_associations, @modules, [:content_tags])
ActiveRecord::Associations::Preloader.new(@modules, :content_tags).run
@modules.each{|m| m.evaluate_for(@current_user) }
session[:module_progressions_initialized] = true
end

View File

@ -502,7 +502,7 @@ class ConversationsController < ApplicationController
messages = nil
Shackles.activate(:slave) do
messages = @conversation.messages
ConversationMessage.send(:preload_associations, messages, :asset)
ActiveRecord::Associations::Preloader.new(messages, :asset).run
end
render :json => conversation_json(@conversation,

View File

@ -701,9 +701,10 @@ class CoursesController < ApplicationController
if includes.include?('enrollments')
# not_ended_enrollments for enrollment_json
# enrollments course for has_grade_permissions?
User.send(:preload_associations, users, { :not_ended_enrollments => :course },
ActiveRecord::Associations::Preloader.new(users,
{ :not_ended_enrollments => :course },
:conditions => ['enrollments.course_id = ?', @context.id],
:shard => @context.shard)
:shard => @context.shard).run
end
render :json => users.map { |u|
enrollments = u.not_ended_enrollments if includes.include?('enrollments')
@ -751,9 +752,10 @@ class CoursesController < ApplicationController
if includes.include?('enrollments')
# not_ended_enrollments for enrollment_json
# enrollments course for has_grade_permissions?
User.send(:preload_associations, users, {:not_ended_enrollments => :course},
ActiveRecord::Associations::Preloader.new(users,
{:not_ended_enrollments => :course},
:conditions => ['enrollments.course_id = ?', @context.id],
:shard => @context.shard)
:shard => @context.shard).run
end
user = users.first or raise ActiveRecord::RecordNotFound
enrollments = user.not_ended_enrollments if includes.include?('enrollments')
@ -1522,7 +1524,7 @@ class CoursesController < ApplicationController
:search_method => @context.user_list_search_mode_for(@current_user),
:initial_type => params[:enrollment_type])
if !@context.concluded? && (@enrollments = EnrollmentsFromUserList.process(list, @context, enrollment_options))
Enrollment.send(:preload_associations, @enrollments, [:course_section, {:user => [:communication_channel, :pseudonym]}])
ActiveRecord::Associations::Preloader.new(@enrollments, [:course_section, {:user => [:communication_channel, :pseudonym]}]).run
json = @enrollments.map { |e|
{ 'enrollment' =>
{ 'associated_user_id' => e.associated_user_id,

View File

@ -243,7 +243,7 @@ class EnrollmentsApiController < ApplicationController
enrollments,
self, send("api_v1_#{endpoint_scope}_enrollments_url"))
Enrollment.send(:preload_associations, enrollments, [:user, :course, :course_section])
ActiveRecord::Associations::Preloader.new(enrollments, [:user, :course, :course_section]).run
includes = [:user] + Array(params[:include])
user_json_preloads(enrollments.map(&:user))

View File

@ -305,7 +305,7 @@
# paginate the indexed scope and then convert to actual Version records
path = api_v1_gradebook_history_feed_url(@context, params)
indexed_versions = Api.paginate(indexed_versions, self, path)
SubmissionVersion.send(:preload_associations, indexed_versions, :version)
ActiveRecord::Associations::Preloader.new(indexed_versions, :version).run
versions = indexed_versions.map(&:version)
# render them

View File

@ -320,7 +320,7 @@ class OutcomeGroupsApiController < ApplicationController
end
# preload the links' outcomes' contexts.
ContentTag.send(:preload_associations, @links, :learning_outcome_content => :context)
ActiveRecord::Associations::Preloader.new(@links, :learning_outcome_content => :context).run
# render to json and serve
render :json => @links.map{ |link| outcome_link_json(link, @current_user, session) }

View File

@ -88,7 +88,7 @@ class SubAccountsController < ApplicationController
def show
@sub_account = subaccount_or_self(params[:id])
Account.send(:preload_associations, @sub_account, [{:sub_accounts => [:parent_account, :root_account]}, {:courses => [:account, :root_account]}])
ActiveRecord::Associations::Preloader.new(@sub_account, [{:sub_accounts => [:parent_account, :root_account]}, {:courses => [:account, :root_account]}]).run
render :json => @sub_account.as_json(:include => [:sub_accounts, :courses], :methods => [:course_count, :sub_account_count])
end

View File

@ -506,7 +506,7 @@ class SubmissionsApiController < ApplicationController
def bulk_load_attachments_and_previews(submissions)
Submission.bulk_load_versioned_attachments(submissions)
attachments = submissions.flat_map &:versioned_attachments
Attachment.send :preload_associations, attachments,
[:canvadoc, :crocodoc_document]
ActiveRecord::Associations::Preloader.new(attachments,
[:canvadoc, :crocodoc_document]).run
end
end

View File

@ -44,7 +44,7 @@ class UserNotesController < ApplicationController
@users = @users.select("name, users.id, last_user_note").order("last_user_note").order_by_sortable_name
@users = @users.paginate(:page => params[:page], :per_page => 20, :total_entries=>count)
# rails gets confused by :include => :courses, because has_current_student_enrollments above references courses in a subquery
User.send(:preload_associations, @users, :courses)
ActiveRecord::Associations::Preloader.new(@users, :courses).run
end
end

View File

@ -132,7 +132,7 @@ class UsersController < ApplicationController
return
end
Enrollment.send(:preload_associations, @observed_enrollments, :course)
ActiveRecord::Associations::Preloader.new(@observed_enrollments, :course).run
end
end

View File

@ -66,8 +66,8 @@ module SearchHelper
end
add_groups = lambda do |groups|
Group.send(:preload_associations, groups, :group_category)
Group.send(:preload_associations, groups, :group_memberships, conditions: { group_memberships: { user_id: @current_user }})
ActiveRecord::Associations::Preloader.new(groups, :group_category).run
ActiveRecord::Associations::Preloader.new(groups, :group_memberships, conditions: { group_memberships: { user_id: @current_user }}).run
groups.each do |group|
group.can_participate = true
contexts[:groups][group.id] = {

View File

@ -31,7 +31,7 @@ class AccountNotification < ActiveRecord::Base
def self.for_user_and_account(user, account)
current = self.for_account(account)
preload_associations(current, [:account, :account_notification_roles])
ActiveRecord::Associations::Preloader.new(current, [:account, :account_notification_roles]).run
user_role_types = {}
current.select! do |announcement|

View File

@ -468,7 +468,7 @@ class Conversation < ActiveRecord::Base
end
def subscribed_participants
ConversationParticipant.send(:preload_associations, conversation_participants, :user) unless ModelCache[:users]
ActiveRecord::Associations::Preloader.new(conversation_participants, :user).run unless ModelCache[:users]
conversation_participants.select(&:subscribed?).map(&:user).compact
end

View File

@ -414,7 +414,7 @@ class Course < ActiveRecord::Base
if courses_or_course_ids.first.is_a? Course
courses = courses_or_course_ids
Course.send(:preload_associations, courses, :course_sections => :nonxlist_course)
ActiveRecord::Associations::Preloader.new(courses, :course_sections => :nonxlist_course).run
course_ids = courses.map(&:id)
else
course_ids = courses_or_course_ids

View File

@ -293,8 +293,8 @@ class StreamItem < ActiveRecord::Base
def self.prepare_object_for_unread(object)
case object
when DiscussionTopic
DiscussionTopic.send(:preload_associations, object, :discussion_topic_participants)
when DiscussionTopic
ActiveRecord::Associations::Preloader.new(object, :discussion_topic_participants).run
end
end

View File

@ -190,9 +190,9 @@ class SubmissionComment < ActiveRecord::Base
end
def self.preload_attachments(comments)
SubmissionComment.send :preload_associations, comments, [:associated_attachments, :submission]
ActiveRecord::Associations::Preloader.new(comments, [:associated_attachments, :submission]).run
submissions = comments.map(&:submission).uniq
Submission.send :preload_associations, submissions, :assignment => :attachments
ActiveRecord::Associations::Preloader.new(submissions, :assignment => :attachments).run
end
def update_submission

View File

@ -1421,7 +1421,7 @@ class User < ActiveRecord::Base
expecting_submission.
not_ignored_by(self, 'grading').
need_grading_info(limit)
Assignment.send :preload_associations, as, :context
ActiveRecord::Associations::Preloader.new(as, :context).run
as.reject{|a| Assignments::NeedsGradingCountQuery.new(a, self).count == 0 }
end
# outer limit, since there could be limit * n_shards results
@ -1614,7 +1614,7 @@ class User < ActiveRecord::Base
end
pending_enrollments = temporary_invitations
unless pending_enrollments.empty?
Enrollment.send(:preload_associations, pending_enrollments, :course)
ActiveRecord::Associations::Preloader.new(pending_enrollments, :course).run
res.concat(pending_enrollments.map { |e| c = e.course; c.write_attribute(:primary_enrollment, e.type); c.write_attribute(:primary_enrollment_rank, e.rank_sortable.to_s); c.write_attribute(:primary_enrollment_state, e.workflow_state); c.write_attribute(:invitation, e.uuid); c })
res.uniq!
end
@ -1653,7 +1653,7 @@ class User < ActiveRecord::Base
end
end + temporary_invitations
if opts[:preload_courses]
Enrollment.send(:preload_associations, enrollments, [:course])
ActiveRecord::Associations::Preloader.new(enrollments, :course).run
end
enrollments
end
@ -1727,7 +1727,7 @@ class User < ActiveRecord::Base
submissions = submissions.uniq
submissions.first(opts[:limit])
Submission.send(:preload_associations, submissions, [:assignment, :user, :submission_comments])
ActiveRecord::Associations::Preloader.new(submissions, [:assignment, :user, :submission_comments]).run
submissions
end
end

View File

@ -57,7 +57,7 @@ TEXT
<div id="context_modules" tabindex="0" aria-label="<%= t('headings.course_modules', %{Course Modules}) %>" class="<%= 'editable' if can_do(@context, @current_user, :manage_content) %>">
<% editable = can_do(@context, @current_user, :manage_content) %>
<% cache([@context.cache_key, editable, 'all_context_modules_6', collection_cache_key(@modules)].join('/')) do %>
<% ContextModule.send(:preload_associations, @modules, :content_tags => :content) %>
<% ActiveRecord::Associations::Preloader.new(@modules, :content_tags => :content).run %>
<% @modules.each do |m| %>
<%= render :partial => 'context_modules/context_module', :object => m, :locals => {:editable => editable } %>
<% end %>

View File

@ -232,7 +232,7 @@ TEXT
<% cache_key = cache_key_items.join('/') %>
<% cache_key = add_menu_tools_to_cache_key(cache_key) %>
<% cache(cache_key) do %>
<% ContextModule.send(:preload_associations, @modules, :content_tags => :content) %>
<% ActiveRecord::Associations::Preloader.new(@modules, :content_tags => :content).run %>
<% @modules.each do |m| %>
<%= render :partial => 'context_modules/context_module_next', :object => m, :locals => {:editable => editable } %>
<% end %>

View File

@ -1,14 +1,6 @@
require 'active_support/callbacks/suspension'
class ActiveRecord::Base
# XXX: Rails3 There are lots of issues with these patches in Rails3 still
class << self
def preload_associations(records, associations, preload_options={})
ActiveRecord::Associations::Preloader.new(records, associations, preload_options).run
end
end
def write_attribute(*args)
value = super
value.is_a?(ActiveRecord::AttributeMethods::Serialization::Attribute) ? value.value : value

View File

@ -43,7 +43,7 @@ module Api::V1::AssignmentOverride
def assignment_override_collection(assignment, include_students=false)
overrides = AssignmentOverrideApplicator.overrides_for_assignment_and_user(assignment, @current_user)
if include_students
AssignmentOverride.send(:preload_associations, overrides, :assignment_override_students)
ActiveRecord::Associations::Preloader.new(overrides, :assignment_override_students).run
end
overrides
end

View File

@ -105,7 +105,7 @@ module Api::V1::CalendarEvent
events = can_read_child_events ? event.child_events.to_a : event.child_events_for(participant)
# do some preloads
CalendarEvent.send(:preload_associations, events, :context)
ActiveRecord::Associations::Preloader.new(events, :context).run
if events.first.context.is_a?(User) && user_json_is_admin?(@context, user)
user_json_preloads(events.map(&:context))
end
@ -167,7 +167,7 @@ module Api::V1::CalendarEvent
if include.include?('appointments')
if include.include?('child_events')
all_child_events = group.appointments.map(&:child_events).flatten
CalendarEvent.send(:preload_associations, all_child_events, :context)
ActiveRecord::Associations::Preloader.new(all_child_events, :context).run
user_json_preloads(all_child_events.map(&:context)) if !all_child_events.empty? && all_child_events.first.context.is_a?(User) && user_json_is_admin?(@context, user)
end
hash['appointments'] = group.appointments.map { |event| calendar_event_json(event, user, session,

View File

@ -50,11 +50,11 @@ module Api::V1
def versions_json(course, versions, api_context, opts={})
# preload for efficiency
unless opts[:submission]
::Version.send(:preload_associations, versions, :versionable)
ActiveRecord::Associations::Preloader.new(versions, :versionable).run
submissions = versions.map(&:versionable)
::Submission.send(:preload_associations, submissions, :assignment) unless opts[:assignment]
::Submission.send(:preload_associations, submissions, :user) unless opts[:student]
::Submission.send(:preload_associations, submissions, :grader)
ActiveRecord::Associations::Preloader.new(submissions, :assignment).run unless opts[:assignment]
ActiveRecord::Associations::Preloader.new(submissions, :user).run unless opts[:student]
ActiveRecord::Associations::Preloader.new(submissions, :grader).run
end
versions.map do |version|

View File

@ -29,10 +29,10 @@ module Api::V1::User
def user_json_preloads(users, preload_email=false)
# pseudonyms for User#sis_pseudoym_for and User#find_pseudonym_for_account
# pseudonyms account for Pseudonym#works_for_account?
User.send(:preload_associations, users, [{ :pseudonyms => :account }]) if user_json_is_admin?
ActiveRecord::Associations::Preloader.new(users, pseudonyms: :account).run if user_json_is_admin?
if preload_email && (no_email_users = users.reject(&:email_cached?)).present?
# communication_channels for User#email if it is not cached
User.send(:preload_associations, no_email_users, :communication_channels)
ActiveRecord::Associations::Preloader.new(no_email_users, :communication_channels).run
end
end

View File

@ -31,12 +31,12 @@ class EnrollmentDateBuilder
def self.preload(enrollments)
return if enrollments.empty?
courses_loaded = enrollments.first.association(:course).loaded?
Enrollment.send(:preload_associations, enrollments, :course) unless courses_loaded
ActiveRecord::Associations::Preloader.new(enrollments, :course).run unless courses_loaded
to_preload = enrollments.reject { |e| fetch(e) }
return if to_preload.empty?
Enrollment.send(:preload_associations, to_preload, :course_section)
Course.send(:preload_associations, to_preload.map(&:course).uniq, :enrollment_term)
ActiveRecord::Associations::Preloader.new(to_preload, :course_section).run
ActiveRecord::Associations::Preloader.new(to_preload.map(&:course).uniq, :enrollment_term).run
to_preload.each { |e| build(e) }
end

View File

@ -905,7 +905,7 @@ describe ContextModule do
# if tags are preloaded we shouldn't filter by a scope (as that requires re-fetching the tags)
it "should not reload the tags if already loaded" do
ContentTag.expects(:visible_to_students_with_da_enabled).never
ContextModule.send(:preload_associations, [@module], {:content_tags => :content})
ActiveRecord::Associations::Preloader.new(@module, content_tags: :content).run
@module.content_tags_visible_to(@student_1)
end
# if tags are not preloaded we should filter by a scope (as will be quicker than filtering an array)