arel-ify lib

excluding api_find, which needs more work

refs CNVS-4706

Change-Id: I013d0660ff2b8dbe2abf6a5c973bd1203f432f99
Reviewed-on: https://gerrit.instructure.com/18921
Reviewed-by: Jacob Fugal <jacob@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
QA-Review: Clare Hetherington <clare@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2013-03-19 09:49:31 -06:00
parent d9111f5414
commit 5ffbcbeb05
63 changed files with 253 additions and 289 deletions

View File

@ -158,8 +158,7 @@ class GroupsController < ApplicationController
format.json do
@groups = BookmarkedCollection.with_each_shard(
Group::Bookmarker,
@current_user.current_groups,
:include => :group_category)
@current_user.current_groups) { |scope| scope.includes(:group_category) }
@groups = Api.paginate(@groups, self, api_v1_current_user_groups_url)
render :json => @groups.map { |g| group_json(g, @current_user, session) }
end

View File

@ -44,9 +44,9 @@ class StreamItemInstance < ActiveRecord::Base
# Runs update_all() and also invalidates cache keys for the array of contexts (a context
# is an array of [context_type, context_id])
def update_all_with_invalidation(contexts, updates, conditions = nil, options = {})
def update_all_with_invalidation(contexts, updates)
contexts.each { |context| StreamItemCache.invalidate_context_stream_item_key(context.first, context.last) }
self.original_update_all(updates, conditions, options)
self.original_update_all(updates)
end
end

View File

@ -2333,7 +2333,7 @@ class User < ActiveRecord::Base
# mfa settings for a user are the most restrictive of any pseudonyms the user has
# a login for
def mfa_settings
result = self.all_pseudonyms(:include => :account).map(&:account).uniq.map do |account|
result = self.pseudonyms.with_each_shard { |scope| scope.includes(:account) }.map(&:account).uniq.map do |account|
case account.mfa_settings
when :disabled
0
@ -2419,19 +2419,19 @@ class User < ActiveRecord::Base
end
def accounts
self.account_users.with_each_shard(:include => :account).map(&:account).uniq
self.account_users.with_each_shard { |scope| scope.includes(:account) }.map(&:account).uniq
end
memoize :accounts
def all_pseudonyms(options = {})
self.pseudonyms.with_each_shard(options)
def all_pseudonyms
self.pseudonyms.with_each_shard
end
memoize :all_pseudonyms
def all_active_pseudonyms(*args)
args.unshift(:conditions => {:workflow_state => 'active'})
all_pseudonyms(*args)
def all_active_pseudonyms
self.pseudonyms.with_each_shard { |scope| scope.active }
end
memoize :all_active_pseudonyms
def prefers_gradebook2?
preferences[:use_gradebook2] != false

View File

@ -42,7 +42,7 @@ module Api::V1::AssignmentOverride
def assignment_override_scope(assignment, include_students=false)
scope = assignment.overrides_visible_to(@current_user)
scope = scope.scoped(:include => :assignment_override_students) if include_students
scope = scope.includes(:assignment_override_students) if include_students
scope
end
@ -50,10 +50,10 @@ module Api::V1::AssignmentOverride
scope = assignment_override_scope(assignment)
case set_or_id
when CourseSection, Group
scope.scoped(:conditions => {
scope.where(
:set_type => set_or_id.class.to_s,
:set_id => set_or_id.id
}).first
:set_id => set_or_id
).first
when nil
nil
else
@ -62,8 +62,8 @@ module Api::V1::AssignmentOverride
end
def find_group(assignment, group_id)
scope = Group.active.scoped(:conditions => {:context_type => 'Course'}).scoped(:conditions => "group_category_id IS NOT NULL")
scope = scope.scoped(:conditions => {:context_id => assignment.context_id, :group_category_id => assignment.group_category_id}) if assignment
scope = Group.active.where(:context_type => 'Course').where("group_category_id IS NOT NULL")
scope = scope.where(:context_id => assignment.context_id, :group_category_id => assignment.group_category_id) if assignment
group = scope.find(group_id)
raise ActiveRecord::RecordNotFound unless group.grants_right?(@current_user, session, :read)
group
@ -71,7 +71,7 @@ module Api::V1::AssignmentOverride
def find_section(context, section_id)
scope = CourseSection.active
scope = scope.scoped(:conditions => {:course_id => context.id}) if context
scope = scope.where(:course_id => context) if context
section = api_find(scope, section_id)
raise ActiveRecord::RecordNotFound unless section.grants_right?(@current_user, session, :read)
section
@ -196,8 +196,11 @@ module Api::V1::AssignmentOverride
end
unless defunct_student_ids.empty?
# on Rails 2, the delete_all will do an update_all
# if we don't put the scoped in. weird.
override.assignment_override_students.
scoped(:conditions => {:user_id => defunct_student_ids.to_a}).
where(:user_id => defunct_student_ids.to_a).
scoped.
delete_all
end
end
@ -262,7 +265,7 @@ module Api::V1::AssignmentOverride
# a new override targets the set of a deleted one
unless defunct_override_ids.empty?
assignment.assignment_overrides.
scoped(:conditions => {:id => defunct_override_ids.to_a}).
where(:id => defunct_override_ids.to_a).
each(&:destroy)
end

View File

@ -34,7 +34,7 @@ module Api::V1::Conversation
unless interleave_submissions
result['message_count'] = result[:submissions] ?
result['message_count'] - result[:submissions].size :
conversation.messages.human.scoped(:conditions => "asset_id IS NULL").size
conversation.messages.human.where(:asset_id => nil).count
end
result[:audience] = audience.map(&:id)
result[:audience_contexts] = contexts_for(audience, conversation.local_context_tags)

View File

@ -39,7 +39,7 @@ module Api::V1::DiscussionTopics
url = feeds_topic_format_path(topic.id, code, :rss)
end
children = topic.child_topics.scoped(:select => 'id').map(&:id)
children = topic.child_topics.pluck(:id)
api_json(topic, user, session, {
:only => %w(id title assignment_id delayed_post_at last_reply_at posted_at root_topic_id podcast_has_student_posts),
@ -96,7 +96,7 @@ module Api::V1::DiscussionTopics
json[:read_state] = entry.read_state(user) if user
if includes.include?(:subentries) && entry.root_entry_id.nil?
replies = entry.flattened_discussion_subentries.active.newest_first.find(:all, :limit => 11).to_a
replies = entry.flattened_discussion_subentries.active.newest_first.limit(11).all
unless replies.empty?
json[:recent_replies] = discussion_entry_api_json(replies.first(10), context, user, session, includes)
json[:has_more_replies] = replies.size > 10

View File

@ -82,13 +82,13 @@ module Api::V1
end
def submissions_set(course, api_context, options = {})
collection = ::Submission.for_course(course).scoped(:order => 'graded_at DESC')
collection = ::Submission.for_course(course).order("graded_at DESC")
if options[:date]
date = options[:date]
collection = collection.scoped(:conditions => ["graded_at < ? and graded_at > ?", date.end_of_day, date.beginning_of_day])
collection = collection.where("graded_at<? AND graded_at>?", date.end_of_day, date.beginning_of_day)
else
collection = collection.scoped(:conditions => 'graded_at IS NOT NULL')
collection = collection.where("graded_at IS NOT NULL")
end
if assignment_id = options[:assignment_id]
@ -98,7 +98,7 @@ module Api::V1
if grader_id = options[:grader_id]
if grader_id.to_s == '0'
# yes, this is crazy. autograded submissions have the grader_id of (quiz_id x -1)
collection = collection.scoped(:conditions => 'submissions.grader_id <= 0')
collection = collection.where("submissions.grader_id<=0")
else
collection = collection.scoped_by_grader_id(grader_id)
end

View File

@ -26,11 +26,11 @@ module Api::V1::Section
if includes.include?('students')
proxy = section.enrollments
if user_json_is_admin?
proxy = proxy.scoped(:include => { :user => :pseudonyms })
proxy = proxy.includes(:user => :pseudonyms)
else
proxy = proxy.scoped(:include => :user)
proxy = proxy.includes(:user)
end
res['students'] = proxy.all(:conditions => "type = 'StudentEnrollment'").
res['students'] = proxy.where(:type => 'StudentEnrollment').
map { |e| user_json(e.user, user, session, includes) }
end
res

View File

@ -116,7 +116,7 @@ module Api::V1::StreamItem
opts[:contexts] = contexts if contexts.present?
items = @current_user.shard.activate do
scope = @current_user.visible_stream_item_instances(opts).scoped(:include => :stream_item)
scope = @current_user.visible_stream_item_instances(opts).includes(:stream_item)
Api.paginate(scope, self, self.send(paginate_url, @context)).to_a
end
render :json => items.map(&:stream_item).compact.map { |i| stream_item_json(i, @current_user, session) }

View File

@ -63,7 +63,7 @@ module AssignmentOverrideApplicator
def self.assignment_overriden_for_section(assignment_or_quiz, section)
section_overrides = assignment_or_quiz.assignment_overrides.scoped(:conditions => {:set_type => 'CourseSection', :set_id => section.id})
section_overrides = assignment_or_quiz.assignment_overrides.where(:set_type => 'CourseSection', :set_id => section)
override_for_due_at(assignment_or_quiz, section_overrides)
end
@ -83,13 +83,13 @@ module AssignmentOverrideApplicator
# priority, then group override, then section overrides by position. DO
# NOT exclude deleted overrides, yet
key = assignment_or_quiz.is_a?(Quiz) ? :quiz_id : :assignment_id
adhoc_membership = AssignmentOverrideStudent.scoped(:conditions => {key => assignment_or_quiz.id, :user_id => user.id}).first
adhoc_membership = AssignmentOverrideStudent.where(key => assignment_or_quiz, :user_id => user).first
overrides << adhoc_membership.assignment_override if adhoc_membership
if assignment_or_quiz.is_a?(Assignment) && assignment_or_quiz.group_category && group = user.current_groups.scoped(:conditions => {:group_category_id => assignment_or_quiz.group_category_id}).first
if assignment_or_quiz.is_a?(Assignment) && assignment_or_quiz.group_category && group = user.current_groups.where(:group_category_id => assignment_or_quiz.group_category_id).first
group_override = assignment_or_quiz.assignment_overrides.
scoped(:conditions => {:set_type => 'Group', :set_id => group.id}).
where(:set_type => 'Group', :set_id => group).
first
overrides << group_override if group_override
end
@ -110,11 +110,11 @@ module AssignmentOverrideApplicator
}.map { |v| v[:course_section_id] }
section_overrides = assignment_or_quiz.assignment_overrides.
scoped(:conditions => {:set_type => 'CourseSection', :set_id => section_ids})
where(:set_type => 'CourseSection', :set_id => section_ids)
# TODO add position column to assignment_override, nil for non-section
# overrides, (assignment_or_quiz, position) unique for section overrides
overrides += section_overrides#.scoped(:order => :position)
overrides += section_overrides#.order(:position)
# for each potential override discovered, make sure we look at the
# appropriate version

View File

@ -93,9 +93,9 @@ module BookmarkedCollection
# if pager.current_bookmark
# sortable_name = pager.current_bookmark.to_s
# comparison = (pager.include_bookmark ? ">=" : ">")
# scope = base_scope.scoped(:conditions => [
# scope = base_scope.where(
# "sortable_name #{comparison} ?",
# sortable_name])
# sortable_name)
# end
# users = scope.paginate(:page => 1, :per_page => pager.per_page)
# pager.replace users
@ -138,9 +138,9 @@ module BookmarkedCollection
# if pager.current_bookmark
# sortable_name = pager.current_bookmark.to_s
# comparison = (pager.include_bookmark ? ">=" : ">")
# scope = scope.scoped(:conditions => [
# scope = scope.where(
# "sortable_name #{comparison} ?",
# sortable_name])
# sortable_name)
# end
# scope.order_by_sortable_name
# end
@ -149,8 +149,8 @@ module BookmarkedCollection
# bookmarked_collection = BookmarkedCollection.wrap(UserBookmarker, User.active)
# Api.paginate(bookmarked_collection, ...)
#
def self.wrap(bookmarker, base_scope, options={}, &block)
BookmarkedCollection::WrapProxy.new(bookmarker, base_scope, options, &block)
def self.wrap(bookmarker, base_scope, &block)
BookmarkedCollection::WrapProxy.new(bookmarker, base_scope, &block)
end
# Combines multiple named bookmarked collections into a single collection
@ -232,18 +232,15 @@ module BookmarkedCollection
#
# BookmarkedCollection.with_each_shard(UserBookmarker, @user.courses)
#
# BookmarkedCollection.with_each_shard(UserBookmarker, @user.courses,
# :conditions => {:workflow_state => :active})
#
# BookmarkedCollection.with_each_shard(UserBookmarker, @user.courses) do |scope|
# scope.active
# end
#
def self.with_each_shard(bookmarker, association, options={})
def self.with_each_shard(bookmarker, association)
# not the result of association.with_each_shard because we don't want it to
# flatten our list of pairs
collections = []
association.with_each_shard(options) do |sharded_association|
association.with_each_shard do |sharded_association|
sharded_association = yield sharded_association if block_given?
collections << [Shard.current.id, self.wrap(bookmarker, sharded_association)]
nil

View File

@ -17,10 +17,9 @@
#
class BookmarkedCollection::WrapProxy < BookmarkedCollection::Proxy
def initialize(bookmarker, base_scope, options={})
def initialize(bookmarker, base_scope)
super bookmarker, lambda{ |pager|
scope = base_scope
scope = scope.scoped(options) if options.present?
scope = bookmarker.restrict_scope(scope, pager)
scope = yield scope if block_given?
scope.paginate(:page => 1, :per_page => pager.per_page)

View File

@ -60,8 +60,7 @@ module Canvas::Oauth
end
def self.find_userinfo_access_token(user, developer_key, scopes)
conditions = ["remember_access = ? AND developer_key_id = ?", true, developer_key.id]
user.access_tokens.active.scoped(:conditions => conditions).all.find do |token|
user.access_tokens.active.where(:remember_access => true, :developer_key_id => developer_key).detect do |token|
token.scoped_to?(scopes) && token.scoped_to?(['userinfo'])
end
end

View File

@ -91,8 +91,8 @@ class ContentZipper
filename = assignment_zip_filename(assignment)
submissions = assignment.submissions
if zip_attachment.user && assignment.context.enrollment_visibility_level_for(zip_attachment.user) != :full
visible_student_ids = assignment.context.enrollments_visible_to(zip_attachment.user).find(:all, :select => 'user_id').map(&:user_id)
submissions = submissions.scoped(:conditions => { :user_id => visible_student_ids})
visible_student_ids = assignment.context.enrollments_visible_to(zip_attachment.user).pluck(:user_id)
submissions = submissions.where(:user_id => visible_student_ids)
end
make_zip_tmpdir(filename) do |zip_name|
@logger.debug("creating #{zip_name}")

View File

@ -3,11 +3,11 @@ module DataFixup::AddPseudonymToStudentViewStudents
pseudonym_join = "LEFT OUTER JOIN pseudonyms ON pseudonyms.user_id=users.id AND pseudonyms.workflow_state='active'"
enrollment_join = "INNER JOIN enrollments ON enrollments.user_id=users.id AND enrollments.workflow_state='active' AND enrollments.type='StudentViewEnrollment'"
begin
fake_students = User.find(:all,
:select => "DISTINCT users.id, enrollments.root_account_id",
:joins => "#{pseudonym_join} #{enrollment_join}",
:conditions => "pseudonyms.id IS NULL",
:limit => 1000)
fake_students = User.select("users.id, enrollments.root_account_id").
uniq.
joins("#{pseudonym_join} #{enrollment_join}").
where(:pseudonyms => { :id => nil }).
limit(1000).all
fake_students.each do |fake_student|
fake_student.pseudonyms.create!(:unique_id => Canvas::Security.hmac_sha1("Test Student_#{fake_student.id}")) do |p|
p.account_id = fake_student.read_attribute(:root_account_id)

View File

@ -1,14 +1,14 @@
module DataFixup::DetectAttachmentEncoding
def self.run
begin
attachments = Attachment.find(:all, :conditions => "encoding IS NULL AND content_type LIKE '%text%'", :limit => 5000)
attachments = Attachment.where("encoding IS NULL AND content_type LIKE '%text%'").limit(5000).all
attachments.each do |a|
begin
a.infer_encoding
rescue
# some old attachments may have been cleaned off disk, but not out of the db
Rails.logger.warn "Unable to detect encoding for attachment #{a.id}: #{$!}"
Attachment.update_all({:encoding => ''}, {:id => a.id})
Attachment.where(:id => a).update_all(:encoding => '')
end
end
end until attachments.empty?

View File

@ -25,7 +25,7 @@ module DataFixup::EscapeS3Filenames
end
# A more efficient query could be done using a regular expression, but this should be db agnostic
Attachment.active.find_in_batches(:conditions => "filename LIKE '%[%' or filename like '%]%' or filename like '%\"%'") do |batch|
Attachment.active.where("filename LIKE '%[%' or filename like '%]%' or filename like '%\"%'").find_in_batches do |batch|
batch.each do |attachment|
# Be paranoid...
next unless attachment.filename =~ /[\[\]"]/

View File

@ -1,13 +1,15 @@
module DataFixup::ExcludeDeletedEntriesFromUnreadCount
def self.run
# Deleted all partipant entries for deleted discussion entries
DiscussionEntryParticipant.scoped(:include => :discussion_entry,
:conditions => ["discussion_entries.workflow_state = ?", "deleted"]).destroy_all
DiscussionEntryParticipant.
includes(:discussion_entry).
where(:discussion_entries => { :workflow_state => 'deleted' }).
destroy_all
# Recalculate counts based on active entries minus read entries
DiscussionTopicParticipant.find_each(:include => :discussion_topic) do |participant|
DiscussionTopicParticipant.includes(:discussion_topic).find_each do |participant|
topic = participant.discussion_topic
read_count = topic.discussion_entry_participants.scoped(:conditions => { :user_id => participant.user_id, :workflow_state => "read" }).count
read_count = topic.discussion_entry_participants.where(:user_id => participant.user_id, :workflow_state => "read").count
participant.unread_entry_count = topic.discussion_entries.active.count - read_count
participant.save
end

View File

@ -1,6 +1,6 @@
module DataFixup::FixBulkMessageAttachments
def self.run
ConversationBatch.find_each(:include => :root_conversation_message) do |batch|
ConversationBatch.includes(:root_conversation_message).find_each do |batch|
root_message = batch.root_conversation_message
next unless root_message.has_attachments?
messages = ConversationMessage.find(batch.conversation_message_ids)

View File

@ -2,7 +2,7 @@ module DataFixup
module FixMediaRecordingSubmissionTypes
def self.run
date = Date.strptime(Setting.get('media_recording_type_bad_date', '03/08/2013'), '%m/%d/%Y')
Assignment.find_each(:conditions => ["updated_at > ? AND submission_types LIKE '%online_media_recording%'", date]) do |assign|
Assignment.where("updated_at > ? AND submission_types LIKE '%online_media_recording%'", date).find_each do |assign|
assign.submission_types = assign.submission_types.gsub('online_media_recording', 'media_recording')
assign.save!
end

View File

@ -1,9 +1,11 @@
module DataFixup
module FixRootOutcomeGroupTitles
def self.run
LearningOutcomeGroup.find_in_batches(:include => :context,
:conditions => {:title => 'ROOT', :context_type => 'Course'}) do |batch|
batch.each { |group| group.update_attribute(:title, group.context.name) }
LearningOutcomeGroup.includes(:context).
where(:title => 'ROOT', :context_type => 'Course').find_in_batches do |batch|
LearningOutcomeGroup.send(:with_exclusive_scope) do
batch.each { |group| group.update_attribute(:title, group.context.name) }
end
end
end
end

View File

@ -1,10 +1,9 @@
module DataFixup::InitializeSubmissionLateness
def self.run
Submission.find_in_batches(
:conditions => "submissions.submitted_at IS NOT NULL AND assignments.due_at IS NOT NULL AND assignments.due_at < submissions.submitted_at",
:joins => :assignment
) do |submissions|
Submission.update_all({:late => true}, {:id => submissions.map(&:id)})
Submission.joins(:assignment).
where("submissions.submitted_at IS NOT NULL AND assignments.due_at IS NOT NULL AND assignments.due_at < submissions.submitted_at").
find_in_batches do |submissions|
Submission.where(:id => submissions).update_all(:late => true)
end
AssignmentOverride.find_each do |override|

View File

@ -1,6 +1,6 @@
module DataFixup::MigrateIgnores
def self.run
User.scoped(:conditions => "preferences LIKE '%ignore%'").find_each do |user|
User.where("preferences LIKE '%ignore%'").find_each do |user|
user.preferences[:ignore].each do |purpose, assets|
assets.each do |asset, details|
begin

View File

@ -4,10 +4,10 @@ module DataFixup::MoveAccountMembershipTypesToRoles
# Look for accounts with membership types
# make 'active' roles for each of them, if they don't exist already
Account.find_in_batches(:conditions => "membership_types IS NOT NULL",
:select => "id, membership_types") do |accounts|
roles = Role.all(:conditions => {:account_id => accounts}, :select => "account_id, name")
account_users = AccountUser.all(:conditions => {:account_id => accounts}, :select => "account_id, membership_type", :group => "account_id, membership_type")
Account.where("membership_types IS NOT NULL").select([:id, :membership_types]).
find_in_batches do |accounts|
roles = Role.where(:account_id => accounts).select([:account_id, :name]).all
account_users = AccountUser.where(:account_id => accounts).select([:account_id, :membership_type]).uniq.all
accounts.each do |account|
names = roles.select{|r| r.account_id == account.id}.collect(&:name) + RoleOverride::KNOWN_ROLE_TYPES
@ -41,10 +41,10 @@ module DataFixup::MoveAccountMembershipTypesToRoles
# Step 2.
# then look for the role overrides that are referencing to a (presumably) deleted membership type
# and make 'inactive' roles for each of them, if they don't exist already
RoleOverride.all(:conditions => ['context_type = ? AND enrollment_type NOT IN (?)', 'Account', RoleOverride::KNOWN_ROLE_TYPES],
:group => 'context_id, enrollment_type',
:select => 'context_id, enrollment_type').each_slice(500) do |role_overrides|
roles = Role.all(:conditions => {:account_id => role_overrides.collect(&:context_id).uniq}, :select => "account_id, name")
RoleOverride.where("context_type='Account' AND enrollment_type NOT IN (?)", RoleOverride::KNOWN_ROLE_TYPES).
uniq.
select([:context_id, :enrollment_type]).each_slice(500) do |role_overrides|
roles = Role.where(:account_id => role_overrides.collect(&:context_id).uniq).select([:account_id, :name]).all
role_overrides_to_add_for = role_overrides.select{|ro| roles.find{|r| r.account_id == ro.context_id && r.name == ro.enrollment_type}.nil?}
role_overrides_to_add_for.each do |ro|

View File

@ -1,16 +1,13 @@
module DataFixup::MoveContentExportNotificationsToMigrationCategory
def self.run
Notification.update_all({ :category => 'Migration' },
{ :name => ['Content Export Finished', 'Content Export Failed'] })
Notification.where(:name => ['Content Export Finished', 'Content Export Failed']).
update_all(:category => 'Migration')
# send immediate notifications only work if you DON'T have a policy for that notification
notification_ids_to_remove = Notification.scoped(
:select => :id,
:conditions => { :category => 'Migration' }
).map(&:id)
notification_ids_to_remove = Notification.where(:category => 'Migration').pluck(:id)
if notification_ids_to_remove.present?
NotificationPolicy.find_ids_in_ranges do |first_id, last_id|
NotificationPolicy.delete_all(["id >= ? AND id <= ? AND notification_id IN (?)", first_id, last_id, notification_ids_to_remove])
NotificationPolicy.where(:id => first_id..last_id, :notification_id => notification_ids_to_remove).delete_all
end
end
end

View File

@ -1,10 +1,10 @@
module DataFixup::PopulateConversationMessageParticipantUserIds
def self.run
target = %w{MySQL Mysql2}.include?(ConversationMessageParticipant.connection.adapter_name) ? 'conversation_message_participants.user_id' : 'user_id'
ConversationMessageParticipant.scoped(:conditions => {:user_id => nil}).find_ids_in_ranges do |min, max|
scope = ConversationMessageParticipant.scoped(:joins => :conversation_participant)
scope.update_all("#{target}=conversation_participants.user_id",
["conversation_message_participants.id>=? AND conversation_message_participants.id <=?", min, max])
ConversationMessageParticipant.where(:user_id => nil).find_ids_in_ranges do |min, max|
scope = ConversationMessageParticipant.joins(:conversation_participant)
scope.where(:conversation_message_participants => { :id => min..max }).
update_all("#{target}=conversation_participants.user_id")
end
end
end

View File

@ -2,10 +2,9 @@ module DataFixup::PopulateConversationMessageProperties
def self.run
ConversationMessage.where("forwarded_message_ids IS NULL").find_ids_in_batches do |ids|
ConversationMessage.update_all [
ConversationMessage.where(:id => ids).update_all(
"has_attachments = (attachment_ids IS NOT NULL AND attachment_ids <> ''), " +
"has_media_objects = (media_comment_id IS NOT NULL)"
], :id => ids
"has_media_objects = (media_comment_id IS NOT NULL)")
end
# infer_defaults will set has_attachments/has_media_objects

View File

@ -1,11 +1,11 @@
module DataFixup::PopulateConversationParticipantPrivateHash
def self.run
target = %w{MySQL Mysql2}.include?(ConversationParticipant.connection.adapter_name) ? 'conversation_participants.private_hash' : 'private_hash'
scope = ConversationParticipant.scoped(:conditions => {:private_hash => nil})
scope = scope.scoped(:joins => :conversation, :conditions => "conversations.private_hash IS NOT NULL")
scope = ConversationParticipant.where(:private_hash => nil)
scope = scope.joins(:conversation).where("conversations.private_hash IS NOT NULL")
scope.find_ids_in_ranges do |min, max|
ConversationParticipant.update_all("#{target}=conversations.private_hash",
["conversation_participants.id>=? AND conversation_participants.id <=?", min, max])
ConversationParticipant.where(:conversation_participants => { :id => min..max }).
update_all("#{target}=conversations.private_hash")
end
end
end

View File

@ -1,11 +1,11 @@
module DataFixup::PopulateConversationParticipantRootAccountIds
def self.run
target = %w{MySQL Mysql2}.include?(ConversationParticipant.connection.adapter_name) ? 'conversation_participants.root_account_ids' : 'root_account_ids'
scope = ConversationParticipant.scoped(:conditions => {:root_account_ids => nil})
scope = scope.scoped(:joins => :conversation, :conditions => "conversations.root_account_ids IS NOT NULL")
scope = ConversationParticipant.where(:root_account_ids => nil)
scope = scope.joins(:conversation).where("conversations.root_account_ids IS NOT NULL")
scope.find_ids_in_ranges do |min, max|
ConversationParticipant.update_all("#{target}=conversations.root_account_ids",
["conversation_participants.id>=? AND conversation_participants.id <=?", min, max])
ConversationParticipant.where(:conversation_participants => { :id => min..max }).
update_all("#{target}=conversations.root_account_ids")
end
end
end

View File

@ -116,7 +116,7 @@ module DataFixup::PopulateConversationRootAccountIds
SQL
# any w/ multiple accounts will have to be reordered in ruby
Conversation.find_each(:conditions => Conversation.wildcard(:root_account_ids, ',')) do |c|
Conversation.where(Conversation.wildcard(:root_account_ids, ',')).find_each do |c|
c.root_account_ids = c.root_account_ids # does a reorder
c.save if c.root_account_ids_changed?
end

View File

@ -27,7 +27,7 @@ SQL
# duplicate!
# we have no way of knowing which one (or both) has stream item instances,
# so just let the first one win
StreamItem.delete_all(:id => si['id'])
StreamItem.where(:id => si['id']).delete_all
end
end
end
@ -45,7 +45,7 @@ SQL
context_type, context_id = ActiveRecord::Base.parse_asset_string(sii['context_code'])
updates[:context_type] = context_type
updates[:context_id] = context_id
StreamItemInstance.update_all(updates, :id => sii['id'])
StreamItemInstance.where(:id => sii['id']).update_all(updates)
end
end
end

View File

@ -1,6 +1,6 @@
module DataFixup::RecalculateCourseAccountAssociations
def self.run
Course.active.scoped(:joins => :root_account, :conditions => "accounts.workflow_state<>'deleted'").find_in_batches do |batch|
Course.active.joins(:root_account).where("accounts.workflow_state<>'deleted'").find_in_batches do |batch|
Course.send(:with_exclusive_scope) do
Course.update_account_associations(batch)
end

View File

@ -1,7 +1,7 @@
module DataFixup::ReintroduceDeletedEntriesToUnreadCount
def self.run
# Recalculate counts to include deleted entries
DiscussionTopicParticipant.find_each(:include => [:discussion_topic, :user]) do |participant|
DiscussionTopicParticipant.includes(:discussion_topic, :user).find_each do |participant|
# since the previous code treated all deleted discussion entries as
# hidden and not included in unread counts, we're going to update all
# pre-existing deleted entries to be marked as read for all users
@ -15,7 +15,7 @@ module DataFixup::ReintroduceDeletedEntriesToUnreadCount
# in theory this count won't need updating, but race conditions mean it
# could be out of sync after the above, so we'll update it here. if it
# doesn't change, the participant won't get re-saved
read_count = topic.discussion_entry_participants.scoped(:conditions => { :user_id => participant.user_id, :workflow_state => "read" }).count
read_count = topic.discussion_entry_participants.where(:user_id => participant.user_id, :workflow_state => "read").count
participant.unread_entry_count = topic.discussion_entries.count - read_count
participant.save
end

View File

@ -1,9 +1,8 @@
module DataFixup::RemoveBogusEnrollmentAssociatedUserIds
def self.run
Enrollment.find_ids_in_ranges do |first, last|
Enrollment.update_all({:associated_user_id => nil},
["associated_user_id IS NOT NULL AND type <> 'ObserverEnrollment' AND id >= ? AND id <= ?",
first, last])
Enrollment.where("associated_user_id IS NOT NULL AND type<>'ObserverEnrollment' AND id>=? AND id<=?", first, last).
update_all(:associated_user_id => nil)
end
end
end

View File

@ -10,10 +10,10 @@ module DataFixup::RemoveDuplicateGroupDiscussions
need_refresh = []
bad_root_topics.each do |context_id, context_type, root_topic_id|
children = DiscussionTopic.scoped({
:conditions => { :context_id => context_id, :context_type => context_type, :root_topic_id => root_topic_id },
:include => :discussion_entries,
}).all.sort_by{ |dt| dt.discussion_entries.length }
children = DiscussionTopic.
where(:context_id => context_id, :context_type => context_type, :root_topic_id => root_topic_id).
includes(:discussion_entries).
sort_by{ |dt| dt.discussion_entries.length }
# keep the active topic with the most entries
deleted_children, active_children = children.partition{ |dt| dt.deleted? }
@ -27,14 +27,13 @@ module DataFixup::RemoveDuplicateGroupDiscussions
# merge all posts on active duplicates to keeper
to_move_entries = active_children.map(&:discussion_entries).flatten.compact
if to_move_entries.present?
DiscussionEntry.update_all({ :discussion_topic_id => keeper.id },
{ :id => to_move_entries.map(&:id) })
DiscussionEntry.where(:id => to_move_entries).update_all(:discussion_topic_id => keeper)
need_refresh << keeper
end
# unlink and delete all duplicate topics
DiscussionTopic.update_all({ :root_topic_id => nil, :assignment_id => nil, :workflow_state => 'deleted' },
{ :id => [deleted_children, active_children].flatten.map(&:id) })
DiscussionTopic.where(:id => deleted_children + active_children).
update_all(:root_topic_id => nil, :assignment_id => nil, :workflow_state => 'deleted')
end
need_refresh.each(&:update_materialized_view)

View File

@ -10,9 +10,9 @@ module DataFixup::RemoveDuplicateNotificationPolicies
HAVING count(*) > 1 LIMIT 50000")
break if ccs.empty?
ccs.each do |cc_id|
scope = NotificationPolicy.scoped(:conditions => { :communication_channel_id => cc_id, :notification_id => nil, :frequency => 'daily' })
keeper = scope.first(:select => "id")
scope.delete_all(["id<>?", keeper.id]) if keeper
scope = NotificationPolicy.where(:communication_channel_id => cc_id, :notification_id => nil, :frequency => 'daily')
keeper = scope.limit(1).pluck(:id).first
scope.where("id<>?", keeper).delete_all if keeper
end
end
end

View File

@ -10,7 +10,7 @@ module DataFixup::RemoveExtraneousConversationTags
WHERE conversation_id = conversations.id
) > 1
COND
Conversation.find_each(:conditions => conditions) do |c|
Conversation.where(conditions).find_each do |c|
fix_private_conversation!(c)
end
end

View File

@ -3,10 +3,8 @@ module DataFixup::RemoveMultipleRootFolders
limit = opts[:limit] || 1000
while (folders = Folder.find(
:all, :conditions => ["workflow_state != ? AND parent_folder_id IS NULL", 'deleted'],
:select => "context_id, context_type", :having => "count(*) > 1", :group => "context_id, context_type", :limit => limit
)
while (folders = Folder.where("workflow_state<>'deleted' AND parent_folder_id IS NULL").
select([:context_id, :context_type]).having("COUNT(*) > 1").group(:context_id, :context_type).limit(limit).all
).any? do
context_types = folders.map(&:context_type).uniq
@ -23,10 +21,10 @@ module DataFixup::RemoveMultipleRootFolders
context_ids = folders.select{|f| f.context_type == context_type}.map(&:context_id)
root_folders = Folder.find(:all, :conditions => [
"context_type = ? AND context_id IN (?) AND workflow_state != ? AND parent_folder_id IS NULL",
context_type, context_ids, 'deleted'
])
root_folders = Folder.where(
"context_type=? AND context_id IN (?) AND workflow_state<>'deleted' AND parent_folder_id IS NULL",
context_type, context_ids
).all
context_ids.each do |context_id|
@ -52,9 +50,9 @@ module DataFixup::RemoveMultipleRootFolders
unless folder.id == main_root_folder.id
Folder.transaction do
if folder.attachments.count > 0 || folder.sub_folders.count > 0
Folder.update_all({:parent_folder_id => main_root_folder.id}, {:id => folder.id})
Folder.where(:id => folder).update_all(:parent_folder_id => main_root_folder)
else
Folder.update_all({:workflow_state => 'deleted'}, {:id => folder.id})
Folder.where(:id => folder).update_all(:workflow_state => 'deleted')
end
end
end

View File

@ -21,7 +21,7 @@ module EportfolioPage
@portfolio.setup_defaults
@categories = @portfolio.eportfolio_categories
if @portfolio.grants_rights?(@current_user, session, :manage)[:manage]
@recent_submissions = @current_user.submissions.find(:all, :order => 'created_at DESC') if @current_user && @current_user == @portfolio.user
@recent_submissions = @current_user.submissions.order("created_at DESC").all if @current_user && @current_user == @portfolio.user
@files = @current_user.attachments.to_a
@folders = @current_user.active_folders_detailed.to_a
end

View File

@ -26,7 +26,7 @@ class GradeCalculator
@course = course :
@course = Course.find(course)
@course_id = @course.id
@groups = @course.assignment_groups.active.scoped(:include => :assignments)
@groups = @course.assignment_groups.active.includes(:assignments)
@assignments = @groups.map(&:assignments).flatten.select { |a|
a.graded? && a.active?
}
@ -57,12 +57,12 @@ class GradeCalculator
def save_scores
raise "Can't save scores when ignore_muted is false" unless @ignore_muted
Course.update_all({:updated_at => Time.now.utc}, {:id => @course.id})
Course.where(:id => @course).update_all(:updated_at => Time.now.utc)
if !@current_updates.empty? || !@final_updates.empty?
query = "updated_at=#{Enrollment.sanitize(Time.now.utc)}"
query += ", computed_current_score=CASE #{@current_updates.join(" ")} ELSE computed_current_score END" unless @current_updates.empty?
query += ", computed_final_score=CASE #{@final_updates.join(" ")} ELSE computed_final_score END" unless @final_updates.empty?
Enrollment.update_all(query, {:user_id => @user_ids, :course_id => @course.id})
Enrollment.where(:user_id => @user_ids, :course_id => @course).update_all(query)
end
end

View File

@ -45,8 +45,8 @@ class GradebookImporter
def parse!
@student_columns = 3 # name, user id, section
# preload a ton of data that presumably we'll be querying
@all_assignments = @context.assignments.active.gradeable.find(:all, :select => 'id, title, points_possible, grading_type').inject({}) { |r, a| r[a.id] = a; r}
@all_students = @context.students.find(:all, :select => 'users.id, name, sortable_name').inject({}) { |r, s| r[s.id] = s; r }
@all_assignments = @context.assignments.active.gradeable.select([:id, :title, :points_possible, :grading_type]).index_by(&:id)
@all_students = @context.students.select(['users.id', :name, :sortable_name]).index_by(&:id)
csv = FasterCSV.new(self.contents, :converters => :nil)
header = csv.shift
@ -72,17 +72,17 @@ class GradebookImporter
@missing_students = @all_students.values - @students if @missing_student
# look up existing score for everything that was provided
@original_submissions = @context.submissions.find(:all,
:select => 'assignment_id, user_id, score',
:include => {:exclude => :quiz_submission},
:conditions => { :assignment_id => (@missing_assignment ? @all_assignments.values : @assignments).map(&:id),
:user_id => (@missing_student ? @all_students.values : @students).map(&:id)}).map do |s|
{
:user_id => s.user_id,
:assignment_id => s.assignment_id,
:score => s.score.to_s
}
end
@original_submissions = @context.submissions.except(:includes).
select([:assignment_id, :user_id, :score]).
where(:assignment_id => (@missing_assignment ? @all_assignments.values : @assignments),
:user_id => (@missing_student ? @all_students.values : @students)).
map do |s|
{
:user_id => s.user_id,
:assignment_id => s.assignment_id,
:score => s.score.to_s
}
end
# cache the score on the existing object
original_submissions_by_student = @original_submissions.inject({}) do |r, s|
@ -199,7 +199,7 @@ class GradebookImporter
protected
def all_pseudonyms
@all_pseudonyms ||= @context.root_account.pseudonyms.active.find(:all, :select => 'id, unique_id, sis_user_id, user_id', :conditions => {:user_id => @all_students.values.map(&:id)})
@all_pseudonyms ||= @context.root_account.pseudonyms.active.select([:id, :unique_id, :sis_user_id, :user_id]).where(:user_id => @all_students.values).all
end
def pseudonyms_by_sis_id

View File

@ -69,10 +69,10 @@ class MessageableUser < User
columns.unshift(head)
end
scope = self.scoped(
:select => MessageableUser.build_select(options),
:group => MessageableUser.connection.group_by(*columns),
:order => 'LOWER(COALESCE(users.short_name, users.name)), users.id')
scope = self.
select(MessageableUser.build_select(options)).
group(MessageableUser.connection.group_by(*columns)).
order("LOWER(COALESCE(users.short_name, users.name)), users.id")
if options[:strict_checks]
scope.where(AVAILABLE_CONDITIONS)

View File

@ -397,7 +397,7 @@ class MessageableUser
ConversationParticipant.where(
:user_id => user_ids,
:conversation_id => conversation.id
).all(:select => 'user_id').map{ |cp| reverse_lookup[cp.user_id] }
).pluck(:user_id).map{ |user_id| reverse_lookup[user_id] }
end
end
@ -561,7 +561,7 @@ class MessageableUser
end
def base_scope(options={})
MessageableUser.prepped(options).scoped(:shard => Shard.current)
MessageableUser.prepped(options).shard(Shard.current)
end
# scopes MessageableUsers via enrollments in courses, setting up the common
@ -586,12 +586,11 @@ class MessageableUser
:common_role_column => 'enrollments.type'
}.merge(options)
base_scope(options).scoped(
:joins => <<-SQL,
base_scope(options).
joins(<<-SQL).where(self.class.enrollment_conditions(options))
INNER JOIN enrollments ON enrollments.user_id=users.id
INNER JOIN courses ON courses.id=enrollments.course_id
SQL
:conditions => self.class.enrollment_conditions(options))
end
# further restricts the enrollment scope to users whose enrollment is
@ -684,8 +683,8 @@ class MessageableUser
:common_role_column => HIGHEST_ENROLLMENT_SQL
}.merge(options)
base_scope(options).scoped(
:joins => "INNER JOIN user_account_associations ON user_account_associations.user_id=users.id")
base_scope(options).
joins("INNER JOIN user_account_associations ON user_account_associations.user_id=users.id")
end
# further restricts the account user scope to users associated with
@ -704,9 +703,9 @@ class MessageableUser
:common_group_column => 'group_id'
}.merge(options)
base_scope(options).scoped(
:joins => "INNER JOIN group_memberships ON group_memberships.user_id=users.id",
:conditions => {'group_memberships.workflow_state' => 'accepted'})
base_scope(options).
joins("INNER JOIN group_memberships ON group_memberships.user_id=users.id").
where(:group_memberships => { :workflow_state => 'accepted' })
end
# further restricts the group user scope to users in groups for which I
@ -759,7 +758,7 @@ class MessageableUser
# already in a with_each_shard from shard_cached, so we can restrict it
# to this shard
@user.observee_enrollments.with_each_shard(Shard.current) do |scope|
scope.scoped(:include => :user).map{ |e| Shard.global_id_for(e.user_id) }
scope.includes(:user).map{ |e| Shard.global_id_for(e.user_id) }
end
end
@ -783,9 +782,7 @@ class MessageableUser
end
def uncached_group_ids_in_courses(courses)
Group.active.scoped(
:select => 'id',
:conditions => {:context_type => 'Course', :context_id => courses.map(&:id)}).map(&:id)
Group.active.where(:context_type => 'Course', :context_id => courses).pluck(:id)
end
def uncached_messageable_sections
@ -793,8 +790,8 @@ class MessageableUser
where(:course_id => fully_visible_courses)
section_visible = CourseSection.
scoped(:joins => :enrollments, :conditions => {'enrollments.user_id' => @user.id}).
where(:course_id => section_visible_courses)
joins(:enrollments).
where(:course_id => section_visible_courses, :enrollments => { :user_id => @user })
(fully_visible + section_visible).
group_by(&:course_id).values.
@ -802,20 +799,22 @@ class MessageableUser
end
def uncached_messageable_groups
fully_visible_scope = GroupMembership.scoped(
:select => 'DISTINCT group_memberships.group_id AS group_id',
:joins => <<-SQL).
fully_visible_scope = GroupMembership.
select("group_memberships.group_id AS group_id").
uniq.
joins(<<-SQL).
INNER JOIN users ON users.id=group_memberships.user_id
INNER JOIN groups ON groups.id=group_memberships.group_id
SQL
where(:workflow_state => 'accepted').
where("groups.workflow_state != 'deleted'").
where("groups.workflow_state<>'deleted'").
where(MessageableUser::AVAILABLE_CONDITIONS).
where(:group_id => fully_visible_group_ids)
section_visible_scope = GroupMembership.scoped(
:select => 'DISTINCT group_memberships.group_id AS group_id',
:joins => <<-SQL).
section_visible_scope = GroupMembership.
select("group_memberships.group_id AS group_id").
uniq.
joins(<<-SQL).
INNER JOIN users ON users.id=group_memberships.user_id
INNER JOIN groups ON groups.id=group_memberships.group_id
INNER JOIN enrollments ON
@ -824,11 +823,11 @@ class MessageableUser
INNER JOIN courses ON courses.id=enrollments.course_id
SQL
where(:workflow_state => 'accepted').
where("groups.workflow_state != 'deleted'").
where("groups.workflow_state<>'deleted'").
where(MessageableUser::AVAILABLE_CONDITIONS).
where('groups.context_type' => 'Course').
where(:groups => { :context_type => 'Course' }).
where(self.class.enrollment_conditions).
where('enrollments.course_section_id' => visible_section_ids_in_courses(recent_section_visible_courses))
where(:enrollments => { :course_section_id => visible_section_ids_in_courses(recent_section_visible_courses) })
if student_courses.present?
section_visible_scope = section_visible_scope.

View File

@ -45,16 +45,14 @@ module Mutable
def hide_stream_items
if self.respond_to? :submissions
stream_items = StreamItem.all(:select => "id, context_type, context_id",
:conditions => { :asset_type => 'Submission', :asset_id => submissions.map(&:id) },
:include => :context)
stream_item_ids = stream_items.map(&:id)
stream_items = StreamItem.select([:id, :context_type, :context_id]).
where(:asset_type => 'Submission', :asset_id => submissions).
includes(:context)
stream_item_contexts = stream_items.map { |si| [si.context_type, si.context_id] }
associated_shards = stream_items.inject([]) { |result, si| result | si.associated_shards }
Shard.with_each_shard(associated_shards) do
StreamItemInstance.update_all_with_invalidation(stream_item_contexts,
{ :hidden => true },
{ :stream_item_id => stream_item_ids })
StreamItemInstance.where(:stream_item_id => stream_items).
update_all_with_invalidation(stream_item_contexts, :hidden => true)
end
end
end
@ -62,16 +60,14 @@ module Mutable
def show_stream_items
if self.respond_to? :submissions
submissions = submissions(:include => {:hidden_submission_comments => :author})
stream_items = StreamItem.all(:select => "id, context_type, context_id",
:conditions => { :asset_type => 'Submission', :asset_id => submissions.map(&:id) },
:include => :context)
stream_item_ids = stream_items.map(&:id)
stream_items = StreamItem.select([:id, :context_type, :context_id]).
where(:asset_type => 'Submission', :asset_id => submissions).
includes(:context)
stream_item_contexts = stream_items.map { |si| [si.context_type, si.context_id] }
associated_shards = stream_items.inject([]) { |result, si| result | si.associated_shards }
Shard.with_each_shard(associated_shards) do
StreamItemInstance.update_all_with_invalidation(stream_item_contexts,
{ :hidden => false },
{ :hidden => true, :stream_item_id => stream_item_ids })
StreamItemInstance.where(:hidden => true, :stream_item_id => stream_items).
update_all_with_invalidation(stream_item_contexts, :hidden => false)
end
outstanding = submissions.map{ |submission|
@ -79,7 +75,7 @@ module Mutable
next if comments.empty?
[submission, comments.map(&:author_id).uniq.size == 1 ? [comments.last.author] : []]
}.compact
SubmissionComment.update_all({ :hidden => false }, { :hidden => true, :submission_id => submissions.map(&:id) })
SubmissionComment.where(:hidden => true, :submission_id => submissions).update_all(:hidden => false)
Submission.send(:preload_associations, outstanding.map(&:first), :visible_submission_comments)
outstanding.each do |submission, skip_users|
submission.create_or_update_conversations!(:create, :skip_users => skip_users)

View File

@ -111,7 +111,7 @@ class NotificationMessageCreator
def build_fallback_for(user)
fallback_channel = immediate_channels_for(user).sort_by(&:path_type).first
fallback_policy = fallback_channel.notification_policies.by('daily').find(:first, :conditions => { :notification_id => nil })
fallback_policy = fallback_channel.notification_policies.by('daily').where(:notification_id => nil).first
fallback_policy ||= NotificationPolicy.new(:communication_channel => fallback_channel,
:frequency => 'daily')
@ -309,9 +309,9 @@ class NotificationMessageCreator
user_id, category = id.split(/_/)
end
messages = Rails.cache.fetch(['recent_messages_for', id].cache_key, :expires_in => 1.hour) do
lookup = Message.scoped(:conditions => ['dispatch_at > ? AND user_id = ? AND to_email = ?', 24.hours.ago, user_id, true])
lookup = Message.where("dispatch_at>? AND user_id=? AND to_email=?", 24.hours.ago, user_id, true)
if category
lookup = lookup.scoped(:conditions => ['notification_category = ?', category.gsub(/_/, " ")])
lookup = lookup.where(:notification_category => category.gsub(/_/, " "))
end
lookup.count
end

View File

@ -4,9 +4,9 @@ module QuizQuestionDataFixer
def self.fix_quiz_questions_with_bad_data
seen_quizzes = {}
# the commit that caused bad AssessmentQuestion data wasn't out until dec 22, 2011, so only try to fix AQs after that.
AssessmentQuestion.find_each(:conditions => ["updated_at > ? AND ((migration_id IS NULL) OR (migration_id IS NOT NULL AND question_data LIKE ?))",
AssessmentQuestion.where("updated_at > ? AND ((migration_id IS NULL) OR (migration_id IS NOT NULL AND question_data LIKE ?))",
Time.zone.parse("Dec 22, 2011"),
"%/files/%"]) do |question|
"%/files/%").find_each do |question|
begin
data = question.question_data
if data && data[:points_possible].nil? && data[:question_type] != "text_only_question"

View File

@ -69,12 +69,12 @@ class CountsReport
data[:media_files_size] = 0
else
timespan = Setting.get('recently_logged_in_timespan', 30.days.to_s).to_i.seconds
enrollment_scope = Enrollment.active.not_fake.scoped(
:joins => {:user => :active_pseudonyms},
:conditions => ["course_id IN (?) AND pseudonyms.last_request_at > ?", course_ids, timespan.ago])
enrollment_scope = Enrollment.active.not_fake.
joins(:user => :active_pseudonyms).
where("course_id IN (?) AND pseudonyms.last_request_at>?", course_ids, timespan.ago)
data[:teachers] = enrollment_scope.count(:user_id, :distinct => true, :conditions => { :type => 'TeacherEnrollment' })
data[:students] = enrollment_scope.count(:user_id, :distinct => true, :conditions => { :type => 'StudentEnrollment' })
data[:teachers] = enrollment_scope.where(:type => 'TeacherEnrollment').count(:user_id, :distinct => true)
data[:students] = enrollment_scope.where(:type => 'StudentEnrollment').count(:user_id, :distinct => true)
data[:users] = enrollment_scope.count(:user_id, :distinct => true)
# ActiveRecord::Base.calculate doesn't support multiple calculations in account single pass
@ -213,13 +213,13 @@ class CountsReport
end
def self.last_activity(account_id)
PageView.maximum(:created_at, :conditions => { :account_id => account_id })
PageView.where(:account_id => account_id).maximum(:created_at)
end
def get_course_ids(account)
is_default_account = account.external_status == ExternalStatuses.default_external_status.to_s
course_ids = []
account.all_courses.scoped(:conditions => { :workflow_state => 'available' }, :select => 'id, updated_at').find_in_batches do |batch|
account.all_courses.where(:workflow_state => 'available').select([:id, :updated_at]).find_in_batches do |batch|
course_ids.concat batch.select { |course| !is_default_account || should_use_default_account_course(course) }.map(&:id)
end
course_ids

View File

@ -25,8 +25,9 @@ module SimpleTags
tags.map{ |tag|
wildcard(quoted_table_name + '.tags', tag, :delimiter => ',')
}
conditions << sanitize_sql(['?', false]) if conditions.empty?
scoped({:conditions => conditions.join(options[:mode] == :or ? " OR " : " AND ")})
conditions.empty? ?
where("?", false) :
where(conditions.join(options[:mode] == :or ? " OR " : " AND "))
end
def tagged_scope_handler(pattern, &block)

View File

@ -25,7 +25,7 @@ module SIS
AbstractCourse.process_as_sis(@sis_options) do
yield importer
end
AbstractCourse.update_all({:sis_batch_id => @batch_id}, {:id => importer.abstract_courses_to_update_sis_batch_id}) if @batch_id && !importer.abstract_courses_to_update_sis_batch_id.empty?
AbstractCourse.where(:id => importer.abstract_courses_to_update_sis_batch_id).update_all(:sis_batch_id => @batch_id) if @batch_id && !importer.abstract_courses_to_update_sis_batch_id.empty?
@logger.debug("AbstractCourses took #{Time.now - start} seconds")
return importer.success_count
end

View File

@ -36,7 +36,7 @@ module SIS
end
Course.update_account_associations(course_ids_to_update_associations.to_a) unless course_ids_to_update_associations.empty?
Course.update_all({:sis_batch_id => @batch_id}, {:id => courses_to_update_sis_batch_id}) if @batch_id && !courses_to_update_sis_batch_id.empty?
Course.where(:id => courses_to_update_sis_batch_id).update_all(:sis_batch_id => @batch_id) if @batch_id && !courses_to_update_sis_batch_id.empty?
@logger.debug("Courses took #{Time.now - start} seconds")
return importer.success_count
end

View File

@ -36,15 +36,15 @@ module SIS
end
end
@logger.debug("Raw enrollments took #{Time.now - start} seconds")
Enrollment.update_all({:sis_batch_id => @batch_id}, {:id => i.enrollments_to_update_sis_batch_ids}) if @batch_id && !i.enrollments_to_update_sis_batch_ids.empty?
Enrollment.where(:id => i.enrollments_to_update_sis_batch_ids).update_all(:sis_batch_id => @batch_id) if @batch_id && !i.enrollments_to_update_sis_batch_ids.empty?
# We batch these up at the end because we don't want to keep touching the same course over and over,
# and to avoid hitting other callbacks for the course (especially broadcast_policy)
Course.update_all({:updated_at => Time.now.utc}, {:id => i.courses_to_touch_ids.to_a}) unless i.courses_to_touch_ids.empty?
Course.where(:id => i.courses_to_touch_ids.to_a).update_all(:updated_at => Time.now.utc) unless i.courses_to_touch_ids.empty?
# We batch these up at the end because normally a user would get several enrollments, and there's no reason
# to update their account associations on each one.
i.incrementally_update_account_associations
User.update_account_associations(i.update_account_association_user_ids.to_a, :account_chain_cache => i.account_chain_cache)
User.update_all({:updated_at => Time.now.utc}, {:id => i.users_to_touch_ids.to_a}) unless i.users_to_touch_ids.empty?
User.where(:id => i.users_to_touch_ids.to_a).update_all(:updated_at => Time.now.utc) unless i.users_to_touch_ids.empty?
@logger.debug("Enrollments with batch operations took #{Time.now - start} seconds")
return i.success_count
end
@ -182,7 +182,7 @@ module SIS
next
end
enrollment = @section.all_enrollments.find(:first, :conditions => { :user_id => user.id, :type => type, :associated_user_id => associated_enrollment.try(:user_id), :role_name => custom_role.try(:name) })
enrollment = @section.all_enrollments.where(:user_id => user, :type => type, :associated_user_id => associated_enrollment.try(:user_id), :role_name => custom_role.try(:name)).first
unless enrollment
enrollment = Enrollment.new
enrollment.root_account = @root_account

View File

@ -45,10 +45,10 @@ module SIS
raise ImportError, "No grade_publishing_status given for enrollment #{enrollment_id}" if grade_publishing_status.blank?
raise ImportError, "Improper grade_publishing_status \"#{grade_publishing_status}\" for enrollment #{enrollment_id}" unless %w{ published error }.include?(grade_publishing_status.downcase)
if (Enrollment.update_all({:grade_publishing_status => grade_publishing_status.downcase,
if (Enrollment.where(:id => enrollment_id, :root_account_id => @root_account).
update_all(:grade_publishing_status => grade_publishing_status.downcase,
:grade_publishing_message => message.to_s,
:updated_at => Time.now.utc},
{:id => enrollment_id, :root_account_id => @root_account.id}) != 1)
:updated_at => Time.now.utc) != 1)
raise ImportError, "Enrollment #{enrollment_id} doesn't exist"
end

View File

@ -28,7 +28,7 @@ module SIS
end
end
Course.update_account_associations(importer.course_ids_to_update_associations.to_a) unless importer.course_ids_to_update_associations.empty?
CourseSection.update_all({:sis_batch_id => @batch_id}, {:id => importer.sections_to_update_sis_batch_ids}) if @batch_id && !importer.sections_to_update_sis_batch_ids.empty?
CourseSection.where(:id => importer.sections_to_update_sis_batch_ids).update_all(:sis_batch_id => @batch_id) if @batch_id && !importer.sections_to_update_sis_batch_ids.empty?
@logger.debug("Sections took #{Time.now - start} seconds")
return importer.success_count
end

View File

@ -34,7 +34,7 @@ module SIS
end
User.update_account_associations(importer.users_to_add_account_associations, :incremental => true, :precalculated_associations => {@root_account.id => 0})
User.update_account_associations(importer.users_to_update_account_associations)
Pseudonym.update_all({:sis_batch_id => @batch_id}, {:id => importer.pseudos_to_set_sis_batch_ids}) if @batch && !importer.pseudos_to_set_sis_batch_ids.empty?
Pseudonym.where(:id => importer.pseudos_to_set_sis_batch_ids).update_all(:sis_batch_id => @batch_id) if @batch && !importer.pseudos_to_set_sis_batch_ids.empty?
@logger.debug("Users took #{Time.now - start} seconds")
return importer.success_count
end
@ -125,7 +125,7 @@ module SIS
if !status_is_active && !user.new_record?
# if this user is deleted, we're just going to make sure the user isn't enrolled in anything in this root account and
# delete the pseudonym.
if 0 < user.enrollments.scoped(:conditions => ["root_account_id = ? AND workflow_state <> ?", @root_account.id, 'deleted']).update_all(:workflow_state => 'deleted')
if 0 < user.enrollments.where("root_account_id=? AND workflow_state<>?", @root_account, 'deleted').update_all(:workflow_state => 'deleted')
should_update_account_associations = true
end
end
@ -182,7 +182,7 @@ module SIS
# find all CCs for this user, and active conflicting CCs for all users
# unless we're deleting this user, then only find CCs for this user
if status_is_active
ccs = CommunicationChannel.scoped(:conditions => ["workflow_state='active' OR user_id=?", user.id])
ccs = CommunicationChannel.where("workflow_state='active' OR user_id=?", user)
else
ccs = user.communication_channels
end
@ -224,7 +224,7 @@ module SIS
if newly_active
other_ccs = ccs.reject { |other_cc| other_cc.user_id == user.id || other_cc.user.nil? || other_cc.user.pseudonyms.active.count == 0 ||
!other_cc.user.pseudonyms.active.scoped(:conditions => ['account_id=? AND sis_user_id IS NOT NULL', @root_account.id]).empty? }
!other_cc.user.pseudonyms.active.where("account_id=? AND sis_user_id IS NOT NULL", @root_account).empty? }
unless other_ccs.empty?
cc.send_merge_notification!
end

View File

@ -121,11 +121,8 @@ module ActiveRecord::Associations
%w{HasManyAssociation HasManyThroughAssociation}.each do |klass|
const_get(klass).class_eval do
def with_each_shard(*shards_or_options)
options = shards_or_options.pop if shards_or_options.last.is_a?(Hash)
def with_each_shard(*shards)
scope = self
# XXX: Rails3 -- fake_arel should help with fixing this and maintaining rails 2 compat
scope = self.scoped(options) if options
scope = yield(scope) if block_given?
Array(scope)
end

View File

@ -364,7 +364,7 @@ class SubmissionList
# A complete list of all graders that have graded submissions for this
# course as User models
def graders
@graders ||= User.find(:all, :conditions => ['id IN (?)', all_grader_ids])
@graders ||= User.where(:id => all_grader_ids).all
end
# A hash of graders by their ids, for easy lookup in full_hash_list
@ -383,7 +383,7 @@ class SubmissionList
# A complete list of all students that have submissions for this course
# as User models
def students
@students ||= User.find(:all, :conditions => ['id IN (?)', all_student_ids])
@students ||= User.where(:id => all_student_ids).all
end
# A hash of students by their ids, for easy lookup in full_hash_list
@ -401,7 +401,7 @@ class SubmissionList
# A complete list of assignments that have submissions for this course
def assignments
@assignments ||= Assignment.find(:all, :conditions => ['id IN (?)', all_assignment_ids])
@assignments ||= Assignment.where(:id => all_assignment_ids).all
end
# A hash of assignments by their ids, for easy lookup in full_hash_list

View File

@ -37,8 +37,8 @@ class SummaryMessageConsolidator
end
dm_id_batches.in_groups_of(Setting.get('summary_message_consolidator_batch_size', '500').to_i, false) do |batches|
DelayedMessage.update_all({ :batched_at => Time.now.utc, :workflow_state => 'sent', :updated_at => Time.now.utc },
{ :id => batches.flatten })
DelayedMessage.where(:id => batches.flatten).
update_all(:batched_at => Time.now.utc, :workflow_state => 'sent', :updated_at => Time.now.utc)
Delayed::Batch.serial_batch do
batches.each do |dm_ids|

View File

@ -147,11 +147,11 @@ class UserList
all_account_ids = [@root_account.id] + @root_account.trusted_account_ids
# Search for matching pseudonyms
Shard.partition_by_shard(all_account_ids) do |account_ids|
Pseudonym.active.find(:all,
:select => 'unique_id AS address, users.name AS name, user_id, account_id',
:joins => :user,
:conditions => ["pseudonyms.workflow_state='active' AND LOWER(unique_id) IN (?) AND account_id IN (?)", @addresses.map {|x| x[:address].downcase}, account_ids]
).map { |pseudonym| pseudonym.attributes.symbolize_keys }.each do |login|
Pseudonym.active.
select('unique_id AS address, users.name AS name, user_id, account_id').
joins(:user).
where("pseudonyms.workflow_state='active' AND LOWER(unique_id) IN (?) AND account_id IN (?)", @addresses.map {|x| x[:address].downcase}, account_ids).
map { |pseudonym| pseudonym.attributes.symbolize_keys }.each do |login|
addresses = @addresses.select { |a| a[:address].downcase == login[:address].downcase }
addresses.each do |address|
# already found a matching pseudonym
@ -182,11 +182,11 @@ class UserList
# create temporary users)
emails = @addresses.select { |a| a[:type] == :email } if @search_method != :open
Shard.partition_by_shard(all_account_ids) do |account_ids|
Pseudonym.active.find(:all,
:select => 'path AS address, users.name AS name, communication_channels.user_id AS user_id, communication_channels.workflow_state AS workflow_state',
:joins => { :user => :communication_channels },
:conditions => ["communication_channels.workflow_state<>'retired' AND LOWER(path) IN (?) AND account_id IN (?)", emails.map { |x| x[:address].downcase}, account_ids]
).map { |pseudonym| pseudonym.attributes.symbolize_keys }.each do |login|
Pseudonym.active.
select('path AS address, users.name AS name, communication_channels.user_id AS user_id, communication_channels.workflow_state AS workflow_state').
joins(:user => :communication_channels).
where("communication_channels.workflow_state<>'retired' AND LOWER(path) IN (?) AND account_id IN (?)", emails.map { |x| x[:address].downcase}, account_ids).
map { |pseudonym| pseudonym.attributes.symbolize_keys }.each do |login|
addresses = emails.select { |a| a[:address].downcase == login[:address].downcase }
addresses.each do |address|
# if all we've seen is unconfirmed, and this one is active, we'll allow this one to overrule
@ -223,12 +223,12 @@ class UserList
end
sms_account_ids = @search_method != :closed ? [@root_account] : all_account_ids
Shard.partition_by_shard(sms_account_ids) do |account_ids|
sms_scope = @search_method != :closed ? Pseudonym : Pseudonym.scoped(:conditions => {:account_id => account_ids})
sms_scope.active.find(:all,
:select => 'path AS address, users.name AS name, communication_channels.user_id AS user_id',
:joins => { :user => :communication_channels },
:conditions => "communication_channels.workflow_state='active' AND (#{smses.map{|x| "path LIKE '#{x[:address].gsub(/[^\d]/, '')}%'" }.join(" OR ")})"
).map { |pseudonym| pseudonym.attributes.symbolize_keys }.each do |sms|
sms_scope = @search_method != :closed ? Pseudonym : Pseudonym.where(:account_id => account_ids)
sms_scope.active.
select('path AS address, users.name AS name, communication_channels.user_id AS user_id').
joins(:user => :communication_channels).
where("communication_channels.workflow_state='active' AND (#{smses.map{|x| "path LIKE '#{x[:address].gsub(/[^\d]/, '')}%'" }.join(" OR ")})").
map { |pseudonym| pseudonym.attributes.symbolize_keys }.each do |sms|
address = sms.delete(:address)[/\d+/]
addresses = smses.select { |a| a[:address].gsub(/[^\d]/, '') == address }
addresses.each do |address|

View File

@ -80,18 +80,18 @@ class UserMerge
from_user.user_services.delete_all
else
from_user.shard.activate do
CommunicationChannel.update_all({:workflow_state => 'retired'}, :id => to_retire_ids) unless to_retire_ids.empty?
CommunicationChannel.where(:id => to_retire_ids).update_all(:workflow_state => 'retired') unless to_retire_ids.empty?
end
from_user.communication_channels.update_all("user_id=#{target_user.id}, position=position+#{max_position}") unless from_user.communication_channels.empty?
from_user.communication_channels.update_all(["user_id=?, position=position+?", target_user, max_position]) unless from_user.communication_channels.empty?
end
Shard.with_each_shard(from_user.associated_shards) do
max_position = Pseudonym.find(:last, :conditions => { :user_id => target_user.id }, :order => 'position').try(:position) || 0
Pseudonym.update_all("position=position+#{max_position}, user_id=#{target_user.id}", :user_id => from_user.id)
max_position = Pseudonym.where(:user_id => target_user).order(:position).last.try(:position) || 0
Pseudonym.where(:user_id => from_user).update_all(["user_id=?, position=position+?", target_user, max_position])
to_delete_ids = []
target_user_enrollments = Enrollment.find(:all, :conditions => { :user_id => target_user.id })
Enrollment.scoped(:conditions => { :user_id => from_user.id }).each do |enrollment|
target_user_enrollments = Enrollment.where(:user_id => target_user).all
Enrollment.where(:user_id => from_user).each do |enrollment|
source_enrollment = enrollment
# non-deleted enrollments should be unique per [course_section, type]
target_enrollment = target_user_enrollments.detect { |enrollment| enrollment.course_section_id == source_enrollment.course_section_id && enrollment.type == source_enrollment.type && !['deleted', 'inactive', 'rejected'].include?(enrollment.workflow_state) }
@ -170,7 +170,7 @@ class UserMerge
to_delete_ids << to_delete.id if to_delete && !['deleted', 'inactive', 'rejected'].include?(to_delete.workflow_state)
end
Enrollment.update_all({:workflow_state => 'deleted'}, :id => to_delete_ids) unless to_delete_ids.empty?
Enrollment.where(:id => to_delete_ids).update_all(:workflow_state => 'deleted') unless to_delete_ids.empty?
[
[:quiz_id, :quiz_submissions],
@ -183,7 +183,7 @@ class UserMerge
# a conflict.
already_there_ids = table.to_s.classify.constantize.find_all_by_user_id(target_user.id).map(&unique_id)
already_there_ids = [0] if already_there_ids.empty?
table.to_s.classify.constantize.update_all({:user_id => target_user.id}, "user_id=#{from_user.id} AND #{unique_id} NOT IN (#{already_there_ids.join(',')})")
table.to_s.classify.constantize.where("user_id=? AND #{unique_id} NOT IN (?)", from_user, already_there_ids).update_all(:user_id => target_user)
rescue => e
logger.error "migrating #{table} column user_id failed: #{e.to_s}"
end
@ -221,10 +221,10 @@ class UserMerge
# delete duplicate observers/observees, move the rest
from_user.user_observees.where(:user_id => target_user.user_observees.map(&:user_id)).delete_all
from_user.user_observees.update_all(:observer_id => target_user.id)
from_user.user_observees.update_all(:observer_id => target_user)
xor_observer_ids = (Set.new(from_user.user_observers.map(&:observer_id)) ^ target_user.user_observers.map(&:observer_id)).to_a
from_user.user_observers.where(:observer_id => target_user.user_observers.map(&:observer_id)).delete_all
from_user.user_observers.update_all(:user_id => target_user.id)
from_user.user_observers.update_all(:user_id => target_user)
# for any observers not already watching both users, make sure they have
# any missing observer enrollments added
target_user.user_observers.where(:observer_id => xor_observer_ids).each(&:create_linked_enrollments)

View File

@ -36,13 +36,13 @@ module UserSearch
users = course.users_visible_to(searcher).uniq.order_by_sortable_name
if enrollment_role
users = users.scoped(:conditions => ["COALESCE(enrollments.role_name, enrollments.type) IN (?) ", enrollment_role])
users = users.where("COALESCE(enrollments.role_name, enrollments.type) IN (?) ", enrollment_role)
elsif enrollment_type
enrollment_type = enrollment_type.map { |e| "#{e.capitalize}Enrollment" }
if enrollment_type.any?{ |et| !Enrollment::READABLE_TYPES.keys.include?(et) }
raise ArgumentError, 'Invalid Enrollment Type'
end
users = users.scoped(:conditions => ["enrollments.type IN (?) ", enrollment_type])
users = users.where(:enrollments => { :type => enrollment_type })
end
users
end

View File

@ -88,14 +88,6 @@ describe "BookmarkedCollection" do
collection.paginate(:per_page => 1).should == [bookmarked_scope.first]
end
it "should apply any options given to the scope" do
course = @scope.scoped(:order => 'courses.id').last
course.update_attributes(:name => 'Matching Name')
collection = BookmarkedCollection.wrap(IDBookmarker, @scope, :conditions => {:name => course.name})
collection.paginate(:per_page => 1).should == [course]
end
it "should apply any restriction block given to the scope" do
course = @scope.order("courses.id").last
course.update_attributes(:name => 'Matching Name')

View File

@ -30,11 +30,10 @@ describe StreamItemInstance do
pending("mocha class method bug") if RUBY_VERSION < "1.9"
# expect
StreamItemCache.expects(:invalidate_context_stream_item_key).twice
updates, conditions, options = ['updates', {:conditions => ''}, {:options => ''}]
StreamItemInstance.expects(:original_update_all).with(updates, conditions, options)
StreamItemInstance.expects(:original_update_all).with('updates')
# when
StreamItemInstance.update_all_with_invalidation(['code_1', 'code_2'],
updates, conditions, options)
'updates')
end
end
end

View File

@ -2079,18 +2079,6 @@ describe User do
@user.all_pseudonyms.should == [@p1, @p2]
end
it "should allow conditions to be passed" do
user_with_pseudonym(:active_all => 1)
@p1 = @pseudonym
@shard1.activate do
account = Account.create!
@p2 = account.pseudonyms.create!(:user => @user, :unique_id => 'abcd')
end
@p1.destroy
@user.all_pseudonyms(:conditions => { :workflow_state => 'active' }).should == [@p2]
end
end
describe "active_pseudonyms" do