arel-ify migrations

refs CNVS-4707

Change-Id: Iac66804015191f91e99e635571134fc575bd3ba8
Reviewed-on: https://gerrit.instructure.com/18751
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Cody Cutrer 2013-03-19 09:48:47 -06:00
parent 6ff362720e
commit 55e1bdbf79
43 changed files with 111 additions and 102 deletions

View File

@ -1,7 +1,7 @@
class AddWorkflowStateToGradingStandards < ActiveRecord::Migration class AddWorkflowStateToGradingStandards < ActiveRecord::Migration
def self.up def self.up
add_column :grading_standards, :workflow_state, :string add_column :grading_standards, :workflow_state, :string
GradingStandard.update_all({:workflow_state => 'active'}) GradingStandard.update_all(:workflow_state => 'active')
end end
def self.down def self.down

View File

@ -1,22 +1,22 @@
class FixDuplicateDiscussions < ActiveRecord::Migration class FixDuplicateDiscussions < ActiveRecord::Migration
def self.up def self.up
DiscussionTopic.transaction do DiscussionTopic.transaction do
duplicate_topics = DiscussionTopic.find(:all, duplicate_topics = DiscussionTopic.
:select => 'old_assignment_id, context_id, context_type', select([:old_assignment_id, :context_id, :context_type]).
:conditions => "old_assignment_id IS NOT NULL AND workflow_state <> 'deleted' AND root_topic_id IS NULL AND context_type='Course'", where("old_assignment_id IS NOT NULL AND workflow_state <> 'deleted' AND root_topic_id IS NULL AND context_type='Course'").
:group => 'old_assignment_id, context_id, context_type HAVING count(*) > 1') group('old_assignment_id, context_id, context_type HAVING COUNT(*) > 1').all
duplicate_topics.each do |topic| duplicate_topics.each do |topic|
duplicates = DiscussionTopic.find(:all, duplicates = DiscussionTopic.
:conditions => ["context_id=? and context_type=? and old_assignment_id=? and workflow_state<>'deleted' and root_topic_id is null", where("context_id=? AND context_type=? AND old_assignment_id=? AND workflow_state<>'deleted' AND root_topic_id is null",
topic.context_id, topic.context_type, topic.old_assignment_id], topic.context_id, topic.context_type, topic.old_assignment_id).
:order => 'updated_at DESC') order('updated_at DESC').
all
to_keep = duplicates.shift to_keep = duplicates.shift
duplicate_ids = duplicates.map(&:id)
DiscussionEntry.update_all("discussion_topic_id=#{to_keep.id}", :discussion_topic_id => duplicate_ids) DiscussionEntry.where(:discussion_topic_id => duplicates).update_all(:discussion_topic_id => to_keep)
DiscussionTopic.update_all("root_topic_id=#{to_keep.id}", :root_topic_id => duplicate_ids) DiscussionTopic.where(:root_topic_id => duplicates).update_all(:root_topic_id => to_keep)
DiscussionTopic.delete(duplicate_ids) DiscussionTopic.delete(duplicates)
end end
end end
end end

View File

@ -1,7 +1,7 @@
class RemoveInactiveEnrollmentState < ActiveRecord::Migration class RemoveInactiveEnrollmentState < ActiveRecord::Migration
def self.up def self.up
Delayed::Backend::ActiveRecord::Job.delete_all(:tag => 'EnrollmentDateRestrictions.update_restricted_enrollments') Delayed::Backend::ActiveRecord::Job.delete_all(:tag => 'EnrollmentDateRestrictions.update_restricted_enrollments')
Enrollment.update_all({:workflow_state => 'active'}, :workflow_state => 'inactive') Enrollment.where(:workflow_state => 'inactive').update_all(:workflow_state => 'active')
end end
def self.down def self.down

View File

@ -1,6 +1,7 @@
class UnscribdTextHtmlAttachments < ActiveRecord::Migration class UnscribdTextHtmlAttachments < ActiveRecord::Migration
def self.up def self.up
Attachment.scoped(:conditions => ["content_type IN ('text/html', 'application/xhtml+xml', 'application/xml', 'text/xml')"]).update_all(:scribd_mime_type_id => nil, :scribd_doc => nil) Attachment.where(:content_type => ['text/html', 'application/xhtml+xml', 'application/xml', 'text/xml']).
update_all(:scribd_mime_type_id => nil, :scribd_doc => nil)
end end
def self.down def self.down

View File

@ -20,21 +20,21 @@ class GroupCategoriesDataMigration < ActiveRecord::Migration
def self.update_records_for_record(record) def self.update_records_for_record(record)
return unless record.context.present? and record.group_category_name.present? return unless record.context.present? and record.group_category_name.present?
category_column = (record.class == Group ? 'category' : 'group_category') category_column = (record.class == Group ? 'category' : 'group_category')
records = record.class.scoped(:conditions => ["context_id=? AND context_type=? AND #{category_column}=? AND group_category_id IS NULL", records = record.class.where("context_id=? AND context_type=? AND #{category_column}=? AND group_category_id IS NULL",
record.context_id, record.context_id,
record.context_type, record.context_type,
record.group_category_name]) record.group_category_name)
records.update_all({:group_category_id => group_category_id_for(record)}) records.update_all(:group_category_id => group_category_id_for(record))
end end
def self.up def self.up
Group.find(:all, :select => "DISTINCT context_id, context_type, category", Group.select([:context_id, :context_type, :category]).uniq.
:conditions => ['context_id IS NOT NULL AND category IS NOT NULL AND group_category_id IS NULL']).each do |record| where('context_id IS NOT NULL AND category IS NOT NULL AND group_category_id IS NULL').each do |record|
update_records_for_record(record) update_records_for_record(record)
end end
Assignment.find(:all, :select => "DISTINCT context_id, context_type, group_category", Assignment.select([:context_id, :context_type, :group_category]).uniq.
:conditions => ['context_id IS NOT NULL AND group_category IS NOT NULL AND group_category_id IS NULL']).each do |record| where('context_id IS NOT NULL AND group_category IS NOT NULL AND group_category_id IS NULL').each do |record|
update_records_for_record(record) update_records_for_record(record)
end end

View File

@ -1,7 +1,7 @@
class UpdateTwitterUrlsForHttps < ActiveRecord::Migration class UpdateTwitterUrlsForHttps < ActiveRecord::Migration
def self.up def self.up
while true while true
users = User.find(:all, :conditions => "avatar_image_source='twitter' AND avatar_image_url NOT LIKE 'https%'", :limit => 500).each do |u| users = User.where("avatar_image_source='twitter' AND avatar_image_url NOT LIKE 'https%'").limit(500).each do |u|
u.avatar_image = { 'type' => 'twitter' } u.avatar_image = { 'type' => 'twitter' }
u.save! u.save!
end end

View File

@ -1,16 +1,16 @@
class DropDeletedUniqueIdFromPseudonyms < ActiveRecord::Migration class DropDeletedUniqueIdFromPseudonyms < ActiveRecord::Migration
def self.up def self.up
Pseudonym.update_all('unique_id=deleted_unique_id', "deleted_unique_id IS NOT NULL AND workflow_state='deleted'") Pseudonym.where("deleted_unique_id IS NOT NULL AND workflow_state='deleted'").update_all('unique_id=deleted_unique_id')
remove_column :pseudonyms, :deleted_unique_id remove_column :pseudonyms, :deleted_unique_id
end end
def self.down def self.down
add_column :pseudonyms, :deleted_unique_id, :string add_column :pseudonyms, :deleted_unique_id, :string
Pseudonym.update_all('deleted_unique_id=unique_id', "unique_id IS NOT NULL AND workflow_state='deleted'") Pseudonym.where("unique_id IS NOT NULL AND workflow_state='deleted'").update_all('deleted_unique_id=unique_id')
if %w{MySQL Mysql2}.include?(Pseudonym.connection.adapter_name) if %w{MySQL Mysql2}.include?(Pseudonym.connection.adapter_name)
Pseudonym.update_all("unique_id=unique_id || '--' || SUBSTR(RAND(), 3, 4)", "unique_id IS NOT NULL AND workflow_state='deleted'") Pseudonym.where("unique_id IS NOT NULL AND workflow_state='deleted'").update_all("unique_id=unique_id || '--' || SUBSTR(RAND(), 3, 4)")
else else
Pseudonym.update_all("unique_id=unique_id || '--' || SUBSTR(CAST(RANDOM() AS varchar), 3, 4)", "unique_id IS NOT NULL AND workflow_state='deleted'") Pseudonym.where("unique_id IS NOT NULL AND workflow_state='deleted'").update_all("unique_id=unique_id || '--' || SUBSTR(CAST(RANDOM() AS varchar), 3, 4)")
end end
end end
end end

View File

@ -5,6 +5,6 @@ class DropSisSourceIdFromPseudonyms < ActiveRecord::Migration
def self.down def self.down
add_column :pseudonyms, :sis_source_id, :string add_column :pseudonyms, :sis_source_id, :string
Pseudonym.update_all('sis_source_id=unique_id', "sis_user_id IS NOT NULL") Pseudonym.where("sis_user_id IS NOT NULL").update_all('sis_source_id=unique_id')
end end
end end

View File

@ -24,16 +24,16 @@ class GroupCategoriesCleanupMigration < ActiveRecord::Migration
def self.update_records_for_record(record) def self.update_records_for_record(record)
return unless record.context.present? and record.group_category_name.present? return unless record.context.present? and record.group_category_name.present?
category_column = (record.class == Group ? 'category' : 'group_category') category_column = (record.class == Group ? 'category' : 'group_category')
records = record.class.scoped(:conditions => ["context_id=? AND context_type=? AND #{category_column}=? AND group_category_id IS NULL", records = record.class.where("context_id=? AND context_type=? AND #{category_column}=? AND group_category_id IS NULL",
record.context_id, record.context_id,
record.context_type, record.context_type,
record.group_category_name]) record.group_category_name)
records.update_all({:group_category_id => group_category_id_for(record)}) records.update_all(:group_category_id => group_category_id_for(record))
end end
def self.up def self.up
Assignment.find(:all, :select => "DISTINCT context_id, context_type, group_category", Assignment.select([:context_id, :context_type, :group_category]).uniq.
:conditions => ['context_id IS NOT NULL AND group_category IS NOT NULL AND group_category_id IS NULL']).each do |record| where('context_id IS NOT NULL AND group_category IS NOT NULL AND group_category_id IS NULL').each do |record|
update_records_for_record(record) update_records_for_record(record)
end end
end end

View File

@ -1,6 +1,6 @@
class UpdateSubmittedAtForDiscussionTopics < ActiveRecord::Migration class UpdateSubmittedAtForDiscussionTopics < ActiveRecord::Migration
def self.up def self.up
Submission.update_all("submitted_at = created_at", ["submission_type = ?", "discussion_topic"]) Submission.where(:submission_type => "discussion_topic").update_all("submitted_at = created_at")
end end
def self.down def self.down

View File

@ -7,7 +7,7 @@ class RestoreUsersSortableName < ActiveRecord::Migration
batch.each do |user| batch.each do |user|
user.sortable_name = nil user.sortable_name = nil
user.sortable_name user.sortable_name
User.update_all({ :sortable_name => user.sortable_name }, :id => user.id) if user.changed? User.where(:id => user).update_all(:sortable_name => user.sortable_name) if user.changed?
end end
end end
end end

View File

@ -87,8 +87,8 @@ class EnsureSubmissionsForDiscussions < ActiveRecord::Migration
end end
# touch all the courses and users # touch all the courses and users
Course.update_all({:updated_at => Time.now.utc}, :id => touched_course_ids.to_a) unless touched_course_ids.empty? Course.where(:id => touched_course_ids.to_a).update_all(:updated_at => Time.now.utc) unless touched_course_ids.empty?
User.update_all({:updated_at => Time.now.utc}, :id => touched_user_ids.to_a) unless touched_user_ids.empty? User.where(:id => touched_user_ids.to_a).update_all(:updated_at => Time.now.utc) unless touched_user_ids.empty?
end end
def self.down def self.down

View File

@ -1,6 +1,11 @@
class DisableOpenRegistrationForDelegatedAuth < ActiveRecord::Migration class DisableOpenRegistrationForDelegatedAuth < ActiveRecord::Migration
def self.up def self.up
Account.root_accounts.find(:all, :joins => :account_authorization_configs, :conditions => { 'account_authorization_configs.auth_type' => ['cas', 'saml']}, :readonly => false).each do |account| if Rails.version < '3'
scope = Account.root_accounts.scoped(:joins => :account_authorization_configs, :readonly => false)
else
scope = Account.root_accounts.joins(:account_authorization_configs).readonly(false)
end
scope.where('account_authorization_configs.auth_type' => ['cas', 'saml']).each do |account|
account.settings = { :open_registration => false } account.settings = { :open_registration => false }
account.save! account.save!
end end

View File

@ -6,9 +6,9 @@ class FixEnrollmentRootAccountId < ActiveRecord::Migration
when 'MySQL', 'Mysql2' when 'MySQL', 'Mysql2'
execute "UPDATE enrollments e, courses c SET e.root_account_id = c.root_account_id WHERE e.course_id = c.id AND e.root_account_id != c.root_account_id" execute "UPDATE enrollments e, courses c SET e.root_account_id = c.root_account_id WHERE e.course_id = c.id AND e.root_account_id != c.root_account_id"
else else
courses = Course.all.each do |c| Course.find_each do |c|
bad_enrollments = c.enrollments.select { |e| e.root_account_id != c.root_account_id }.map(&:id) bad_enrollments = c.enrollments.where("enrollments.root_account_id<>courses.root_account_id").pluck(:id)
Enrollment.update_all({:root_account_id => c.root_account_id}, :id => bad_enrollments) Enrollment.where(:id => bad_enrollments).update_all(:root_account_id => c.root_account_id)
end end
end end
end end

View File

@ -1,9 +1,7 @@
class RecalculateMutedAssignments < ActiveRecord::Migration class RecalculateMutedAssignments < ActiveRecord::Migration
def self.up def self.up
course_ids = Assignment.find(:all, course_ids = Assignment.where(:muted => true, :context_type => 'Course').select(:context_id).uniq.map(&:context_id)
:conditions => ['muted = ? AND context_type = ?', true, 'Course'],
:select => 'distinct context_id').map(&:context_id)
course_ids.each do |id| course_ids.each do |id|
c = Course.find id c = Course.find id
c.recompute_student_scores c.recompute_student_scores

View File

@ -6,7 +6,7 @@ class RemoveAttachmentsWithNoScopeFromList < ActiveRecord::Migration
i = 0 i = 0
# we do one extra loop to avoid race conditions # we do one extra loop to avoid race conditions
while i < Attachment.maximum(:id) + 10000 while i < Attachment.maximum(:id) + 10000
Attachment.update_all({:position => nil}, ["folder_id IS NULL AND id>? AND id <=?", i, i + 10000]) Attachment.where("folder_id IS NULL AND id>? AND id <=?", i, i + 10000).update_all(:position => nil)
sleep 1 sleep 1
i = i + 10000 i = i + 10000
end end

View File

@ -3,8 +3,8 @@ class FixSisCommunicationChannels < ActiveRecord::Migration
def self.up def self.up
begin begin
pseudonym_ids = Pseudonym.find(:all, :select => 'pseudonyms.id', :joins => :sis_communication_channel, :conditions => "pseudonyms.user_id<>communication_channels.user_id", :limit => 1000).map(&:id) pseudonym_ids = Pseudonym.joins(:sis_communication_channel).where("pseudonyms.user_id<>communication_channels.user_id").limit(1000).pluck(:id)
Pseudonym.update_all({:sis_communication_channel_id => nil}, :id => pseudonym_ids) Pseudonym.where(:id => pseudonym_ids).update_all(:sis_communication_channel_id => nil)
sleep 1 sleep 1
end until pseudonym_ids.empty? end until pseudonym_ids.empty?
end end

View File

@ -2,8 +2,8 @@ class DestroyExistingAnonymousFolderDownloads < ActiveRecord::Migration
def self.up def self.up
# There was a bug allowing locked/hidden files to be downloaded in zip files for public # There was a bug allowing locked/hidden files to be downloaded in zip files for public
# courses. This migration will delete those, so that no data leaks remain from the bug. # courses. This migration will delete those, so that no data leaks remain from the bug.
Attachment.update_all({ :workflow_state => 'deleted', :deleted_at => Time.zone.now }, Attachment.where(:context_type => 'Folder', :workflow_state => 'zipped', :user_id => nil).
{ :context_type => 'Folder', :workflow_state => 'zipped', :user_id => nil }) update_all(:workflow_state => 'deleted', :deleted_at => Time.zone.now)
end end
def self.down def self.down

View File

@ -1,6 +1,6 @@
class LabelsToStars < ActiveRecord::Migration class LabelsToStars < ActiveRecord::Migration
def self.up def self.up
ConversationParticipant.update_all("label = 'starred'", "label IS NOT NULL") ConversationParticipant.where("label IS NOT NULL").update_all(:label => 'starred')
end end
def self.down def self.down

View File

@ -11,9 +11,9 @@ class PurgeDuplicateDeletedSisEnrollments < ActiveRecord::Migration
HAVING count(*) > 1 LIMIT 1000") HAVING count(*) > 1 LIMIT 1000")
break if pairs.empty? break if pairs.empty?
pairs.each do |(user_id, course_section_id, type)| pairs.each do |(user_id, course_section_id, type)|
scope = Enrollment.scoped(:conditions => ["user_id=? AND course_section_id=? AND type=? AND sis_source_id IS NOT NULL AND workflow_state='deleted'", user_id.to_i, course_section_id.to_i, type]) scope = Enrollment.where("user_id=? AND course_section_id=? AND type=? AND sis_source_id IS NOT NULL AND workflow_state='deleted'", user_id.to_i, course_section_id.to_i, type)
keeper = scope.first(:select => :id) keeper = scope.limit(1).pluck(:id).first
scope.delete_all(["id<>?", keeper.id]) scope.where("id<>?", keeper).delete_all
end end
end end
end end

View File

@ -3,7 +3,7 @@ class RemoveDuplicateSubmissionMessages < ActiveRecord::Migration
def self.up def self.up
# destroy rather than delete so that callbacks happen # destroy rather than delete so that callbacks happen
ConversationMessage.destroy_all(<<-CONDITIONS) ConversationMessage.where(<<-CONDITIONS).destroy_all
asset_id IS NOT NULL asset_id IS NOT NULL
AND id NOT IN ( AND id NOT IN (
SELECT MIN(id) SELECT MIN(id)

View File

@ -3,10 +3,10 @@ class FixZeroPointPassFailScores < ActiveRecord::Migration
# a bug allowed a few submissions to have their grade set to pass/fail, # a bug allowed a few submissions to have their grade set to pass/fail,
# rather than complete/incomplete. pass/fail is allowed in the api, but was # rather than complete/incomplete. pass/fail is allowed in the api, but was
# supposed to be translated to complete/incomplete in the db. # supposed to be translated to complete/incomplete in the db.
Submission.update_all({ :grade => 'complete' }, { :grade => 'pass' }) Submission.where(:grade => 'pass').update_all(:grade => 'complete')
Submission.update_all({ :grade => 'incomplete' }, { :grade => 'fail' }) Submission.where(:grade => 'fail').update_all(:grade => 'incomplete')
Submission.update_all({ :published_grade => 'complete' }, { :published_grade => 'pass' }) Submission.where(:published_grade => 'pass').update_all(:published_grade => 'complete')
Submission.update_all({ :published_grade => 'incomplete' }, { :published_grade => 'fail' }) Submission.where(:published_grade => 'fail').update_all(:published_grade => 'incomplete')
end end
def self.down def self.down

View File

@ -5,7 +5,7 @@ class RemoveIrrelevantSubmissionMessages < ActiveRecord::Migration
# destroy any submission messages where none of the commenters are # destroy any submission messages where none of the commenters are
# participants in the conversation. in production, this will remove about # participants in the conversation. in production, this will remove about
# 7k rows # 7k rows
ConversationMessage.destroy_all(<<-CONDITIONS) ConversationMessage.where(<<-CONDITIONS).destroy_all
asset_id IS NOT NULL asset_id IS NOT NULL
AND id NOT IN ( AND id NOT IN (
SELECT DISTINCT cm.id SELECT DISTINCT cm.id

View File

@ -1,7 +1,7 @@
class AcceptPendingGroupMemberships < ActiveRecord::Migration class AcceptPendingGroupMemberships < ActiveRecord::Migration
def self.up def self.up
GroupMembership.update_all({ :workflow_state => 'accepted' }, { :workflow_state => 'invited' }) GroupMembership.where(:workflow_state => 'invited').update_all(:workflow_state => 'accepted')
GroupMembership.update_all({ :workflow_state => 'accepted' }, { :workflow_state => 'requested' }) GroupMembership.where(:workflow_state => 'requested').update_all(:workflow_state => 'accepted')
end end
def self.down def self.down

View File

@ -1,6 +1,6 @@
class SetBlankSisUserIdsToNull < ActiveRecord::Migration class SetBlankSisUserIdsToNull < ActiveRecord::Migration
def self.up def self.up
Pseudonym.update_all({ :sis_user_id => nil }, :sis_user_id => '') Pseudonym.where(:sis_user_id => '').update_all(:sis_user_id => nil)
end end
def self.down def self.down

View File

@ -1,6 +1,6 @@
class RemoveDeletedUserAccountAssociations < ActiveRecord::Migration class RemoveDeletedUserAccountAssociations < ActiveRecord::Migration
def self.up def self.up
UserAccountAssociation.delete_all("user_id IN (SELECT id FROM users WHERE workflow_state IN ('deleted', 'creation_pending'))") UserAccountAssociation.where("user_id IN (SELECT id FROM users WHERE workflow_state IN ('deleted', 'creation_pending'))").delete_all
end end
def self.down def self.down

View File

@ -2,8 +2,8 @@ class RemoveUnusedNotificationPolicies < ActiveRecord::Migration
tag :postdeploy tag :postdeploy
def self.up def self.up
ids = Notification.find(:all, :select => 'id', :conditions => { :category => ['Student Message', 'Files']}).map(&:id) ids = Notification.where(:category => ['Student Message', 'Files']).pluck(:id)
NotificationPolicy.delete_all(:notification_id => ids) NotificationPolicy.where(:notification_id => ids).delete_all
end end
def self.down def self.down

View File

@ -3,8 +3,8 @@ class RemoveUnusedNotifications < ActiveRecord::Migration
def self.up def self.up
return unless Shard.current.default? return unless Shard.current.default?
Notification.update_all({:category => 'Other'}, :category => 'Message') Notification.where(:category => 'Message').update_all(:category => 'Other')
Notification.delete_all(:category => ['Files', 'Student Message']) Notification.where(:category => ['Files', 'Student Message']).delete_all
end end
def self.down def self.down

View File

@ -4,11 +4,11 @@ class SetDiscussionEntryRootIds < ActiveRecord::Migration
def self.up def self.up
# fix up parent_id, which was getting set to 0 for root-level entries # fix up parent_id, which was getting set to 0 for root-level entries
# also set root_entry_id to parent_id for all existing entries # also set root_entry_id to parent_id for all existing entries
DiscussionEntry.update_all("parent_id = CASE parent_id WHEN 0 THEN null ELSE parent_id END, root_entry_id = CASE parent_id WHEN 0 THEN null ELSE parent_id END") DiscussionEntry.update_all("parent_id = CASE parent_id WHEN 0 THEN NULL ELSE parent_id END, root_entry_id = CASE parent_id WHEN 0 THEN NULL ELSE parent_id END")
end end
def self.down def self.down
DiscussionEntry.update_all("parent_id = 0", "parent_id IS NULL") DiscussionEntry.where(:parent_id => nil).update_all(:parent_id => 0)
# previous migration drops the root_entry_id column here # previous migration drops the root_entry_id column here
end end
end end

View File

@ -3,7 +3,7 @@ class BreakDownDetailedReportSnapshots < ActiveRecord::Migration
self.transactional = false self.transactional = false
def self.do_report_type(scope) def self.do_report_type(scope)
detailed = scope.find(:last, :conditions => { :account_id => nil }) detailed = scope.where(:account_id => nil).last
return unless detailed return unless detailed
detailed.data['detailed'].each do |(account_id, data)| detailed.data['detailed'].each do |(account_id, data)|
new_detailed = detailed.clone new_detailed = detailed.clone

View File

@ -9,7 +9,7 @@ class FixUserMergeConversations2 < ActiveRecord::Migration
# the previous merging was done incorrectly due to a scoping issue # the previous merging was done incorrectly due to a scoping issue
# there are only about 100 that need to be fixed, so we just load them all # there are only about 100 that need to be fixed, so we just load them all
convos = ConversationParticipant.find(:all, :conditions => "NOT EXISTS (SELECT 1 FROM conversations WHERE id = conversation_id)") convos = ConversationParticipant.where("NOT EXISTS (SELECT 1 FROM conversations WHERE id = conversation_id)")
convos.group_by(&:conversation_id).each do |conversation_id, cps| convos.group_by(&:conversation_id).each do |conversation_id, cps|
private_hash = Conversation.private_hash_for(cps.map(&:user_id)) private_hash = Conversation.private_hash_for(cps.map(&:user_id))
if target = Conversation.find_by_private_hash(private_hash) if target = Conversation.find_by_private_hash(private_hash)
@ -17,7 +17,7 @@ class FixUserMergeConversations2 < ActiveRecord::Migration
cps.each do |cp| cps.each do |cp|
if new_cp = new_participants[cp.user_id] if new_cp = new_participants[cp.user_id]
new_cp.update_attribute(:workflow_state, cp.workflow_state) if cp.unread? || new_cp.archived? new_cp.update_attribute(:workflow_state, cp.workflow_state) if cp.unread? || new_cp.archived?
cp.conversation_message_participants.update_all(["conversation_participant_id = ?", new_cp.id]) cp.conversation_message_participants.update_all(:conversation_participant_id => new_cp)
cp.destroy cp.destroy
else else
$stderr.puts "couldn't find a target ConversationParticipant for id #{cp.id}" $stderr.puts "couldn't find a target ConversationParticipant for id #{cp.id}"

View File

@ -2,12 +2,12 @@ class MoveMigrationNotificationsToSeparateCategory < ActiveRecord::Migration
tag :postdeploy tag :postdeploy
def self.up def self.up
Notification.update_all({ :category => 'Migration' }, Notification.where(:name => ['Migration Export Ready', 'Migration Import Finished', 'Migration Import Failed']).
{ :name => ['Migration Export Ready', 'Migration Import Finished', 'Migration Import Failed'] }) update_all(:category => 'Migration')
end end
def self.down def self.down
Notification.update_all({ :category => 'Other' }, Notification.where(:name => ['Migration Export Ready', 'Migration Import Finished', 'Migration Import Failed']).
{ :name => ['Migration Export Ready', 'Migration Import Finished', 'Migration Import Failed'] }) update_all(:category => 'Other')
end end
end end

View File

@ -6,7 +6,7 @@ class MoveContentExportNotificationsToMigrationCategory < ActiveRecord::Migratio
end end
def self.down def self.down
Notification.update_all({ :category => 'Other' }, Notification.where(:name => ['Content Export Finished', 'Content Export Failed']).
{ :name => ['Content Export Finished', 'Content Export Failed'] }) update_all(:category => 'Other')
end end
end end

View File

@ -4,8 +4,8 @@ class FixDefaultLimitPrivilegesToCourseSection < ActiveRecord::Migration
def self.up def self.up
Enrollment.find_ids_in_ranges do |(start_id, end_id)| Enrollment.find_ids_in_ranges do |(start_id, end_id)|
Enrollment.update_all({ :limit_privileges_to_course_section => false }, ["type IN ('StudentEnrollment', 'ObserverEnrollment', 'StudentViewEnrollment', 'DesignerEnrollment') AND id>=? AND id <=?", start_id, end_id]) Enrollment.where("type IN ('StudentEnrollment', 'ObserverEnrollment', 'StudentViewEnrollment', 'DesignerEnrollment') AND id>=? AND id <=?", start_id, end_id).update_all(:limit_privileges_to_course_section => false)
Enrollment.update_all({ :limit_privileges_to_course_section => false }, ["type IN ('TeacherEnrollment', 'TaEnrollment') AND limit_privileges_to_course_section IS NULL AND id>=? AND id <=?", start_id, end_id]) Enrollment.where("type IN ('TeacherEnrollment', 'TaEnrollment') AND limit_privileges_to_course_section IS NULL AND id>=? AND id <=?", start_id, end_id).update_all(:limit_privileges_to_course_section => false)
end end
end end

View File

@ -2,7 +2,7 @@ class ConstrainAssignmentGroupCategoryIds < ActiveRecord::Migration
tag :postdeploy tag :postdeploy
def self.up def self.up
Assignment.update_all({:group_category_id => nil}, :group_category_id => 0) Assignment.where(:group_category_id => 0).update_all(:group_category_id => nil)
add_foreign_key :assignments, :group_categories add_foreign_key :assignments, :group_categories
end end

View File

@ -4,7 +4,7 @@ class AddUniqueIndexOnFavorites < ActiveRecord::Migration
def self.up def self.up
# cleanup must happen synchronously in order to create the unique index # cleanup must happen synchronously in order to create the unique index
# the extra subquery is necessary to avoid error 1093 on mysql # the extra subquery is necessary to avoid error 1093 on mysql
Favorite.delete_all("id NOT IN (SELECT * FROM (SELECT MIN(id) FROM favorites GROUP BY user_id, context_id, context_type) x)") Favorite.where("id NOT IN (SELECT * FROM (SELECT MIN(id) FROM favorites GROUP BY user_id, context_id, context_type) x)").delete_all
add_index :favorites, [:user_id, :context_id, :context_type], :unique => true, :name => "index_favorites_unique_user_object" add_index :favorites, [:user_id, :context_id, :context_type], :unique => true, :name => "index_favorites_unique_user_object"
end end

View File

@ -9,8 +9,8 @@ class UniquifyWikis < ActiveRecord::Migration
wikis = connection.select_rows("SELECT wiki_id FROM wiki_namespaces WHERE namespace='default' AND context_type='#{context_type}' AND context_id=#{context_id}").map(&:first).map(&:to_i) wikis = connection.select_rows("SELECT wiki_id FROM wiki_namespaces WHERE namespace='default' AND context_type='#{context_type}' AND context_id=#{context_id}").map(&:first).map(&:to_i)
to_keep = context.wiki_id to_keep = context.wiki_id
wikis.delete(to_keep) wikis.delete(to_keep)
WikiPage.update_all({:wiki_id => to_keep}, {:wiki_id => wikis}) WikiPage.where(:wiki_id => wikis).update_all(:wiki_id => to_keep)
Wiki.delete_all(:id => wikis) Wiki.where(:id => wikis).delete_all
connection.execute("DELETE FROM wiki_namespaces WHERE wiki_id IN (#{wikis.join(',')})") connection.execute("DELETE FROM wiki_namespaces WHERE wiki_id IN (#{wikis.join(',')})")
end end
end end

View File

@ -4,7 +4,7 @@ class AddUniqueIndexOnNotifications < ActiveRecord::Migration
def self.up def self.up
return unless Shard.current.default? return unless Shard.current.default?
# the excess subquery is necessary to avoid error 1093 on mysql # the excess subquery is necessary to avoid error 1093 on mysql
Notification.delete_all("id NOT IN (SELECT * FROM (SELECT MIN(id) FROM notifications GROUP BY name) x)") Notification.where("id NOT IN (SELECT * FROM (SELECT MIN(id) FROM notifications GROUP BY name) x)").delete_all
add_index :notifications, [:name], :unique => true, :name => "index_notifications_unique_on_name" add_index :notifications, [:name], :unique => true, :name => "index_notifications_unique_on_name"
end end

View File

@ -8,15 +8,12 @@ class FixProfilePictures < ActiveRecord::Migration
def self.up def self.up
# we don't support twitter or linked in profile pictures anymore, because # we don't support twitter or linked in profile pictures anymore, because
# they are too small # they are too small
ids = User.where(:avatar_image_source => %w(twitter linkedin)).map(&:id) User.where(:avatar_image_source => ['twitter', 'linkedin']).
now = Time.now update_all(
User.update_all(
{
:avatar_image_source => 'no_pic', :avatar_image_source => 'no_pic',
:avatar_image_url => nil, :avatar_image_url => nil,
:avatar_image_updated_at => now :avatar_image_updated_at => Time.now.utc
}, )
:id => ids)
DataFixup::RegenerateUserThumbnails.send_later_if_production(:run) DataFixup::RegenerateUserThumbnails.send_later_if_production(:run)
end end

View File

@ -15,7 +15,7 @@ class HashAccessTokens < ActiveRecord::Migration
:token_hint => at['token'][0,5], :token_hint => at['token'][0,5],
:crypted_token => AccessToken.hashed_token(at['token']), :crypted_token => AccessToken.hashed_token(at['token']),
} }
AccessToken.update_all(updates, { :id => at['id'] }) AccessToken.where(:id => at['id']).update_all(updates)
end end
end end
end end

View File

@ -8,7 +8,7 @@ class AddUniqueIndexOnRoleName < ActiveRecord::Migration
# same name and different base role types; that can't be cleaned up automatically # same name and different base role types; that can't be cleaned up automatically
# (but should not happen because an existing validation prevents this case) # (but should not happen because an existing validation prevents this case)
# note 2: the extra subquery is necessary to avoid error 1093 on mysql # note 2: the extra subquery is necessary to avoid error 1093 on mysql
Role.delete_all("id NOT IN (SELECT * FROM (SELECT MAX(id) FROM roles GROUP BY account_id, name, base_role_type) x)") Role.where("id NOT IN (SELECT * FROM (SELECT MAX(id) FROM roles GROUP BY account_id, name, base_role_type) x)").delete_all
add_index :roles, [:account_id, :name], :unique => true, :name => "index_roles_unique_account_name" add_index :roles, [:account_id, :name], :unique => true, :name => "index_roles_unique_account_name"
end end

View File

@ -4,13 +4,17 @@ class CleanUpUserAccountAssociations < ActiveRecord::Migration
def self.up def self.up
# clean up garbage data # clean up garbage data
UserAccountAssociation.delete_all(:user_id => nil) UserAccountAssociation.where(:user_id => nil).delete_all
# we don't have any of these in production, but just in case... # we don't have any of these in production, but just in case...
UserAccountAssociation.delete_all(:account_id => nil) UserAccountAssociation.where(:account_id => nil).delete_all
# clean up dups by recalculating # clean up dups by recalculating
user_ids = UserAccountAssociation.find(:all, :select => 'DISTINCT user_id', user_ids = UserAccountAssociation.
:group => 'user_id, account_id', :having => 'COUNT(*) > 1').map(&:user_id) select(:user_id).
uniq.
group(:user_id, :account_id).
having("COUNT(*)>1").
map(&:user_id)
User.update_account_associations(user_ids) User.update_account_associations(user_ids)
# add a unique index # add a unique index

View File

@ -4,8 +4,12 @@ class AddUniqueIndexOnCourseAccountAssociations < ActiveRecord::Migration
def self.up def self.up
# clean up any dups first # clean up any dups first
course_ids = CourseAccountAssociation.find(:all, :select => 'DISTINCT course_id', course_ids = CourseAccountAssociation.
:group => 'course_id, course_section_id, account_id', :having => 'COUNT(*) > 1').map(&:course_id) select(:course_id).
uniq.
group(:course_id, :course_section_id, :account_id).
having("COUNT(*)>1").
map(&:course_id)
Course.update_account_associations(course_ids) Course.update_account_associations(course_ids)
add_index :course_account_associations, [:course_id, :course_section_id, :account_id], :unique => true, :concurrently => true, :name => 'index_caa_on_course_id_and_section_id_and_account_id' add_index :course_account_associations, [:course_id, :course_section_id, :account_id], :unique => true, :concurrently => true, :name => 'index_caa_on_course_id_and_section_id_and_account_id'