rails 4.2: fix scope.new calls

scope.new no longer keeps the record out of the association

refs #CNVS-26056

Change-Id: I5867253645c1020cde8853ccc389a0730c241652
Reviewed-on: https://gerrit.instructure.com/70788
Tested-by: Jenkins
Reviewed-by: Cody Cutrer <cody@instructure.com>
Product-Review: James Williams  <jamesw@instructure.com>
QA-Review: James Williams  <jamesw@instructure.com>
This commit is contained in:
James Williams 2016-01-21 13:19:56 -07:00
parent ca36398dbf
commit 9531a37afd
29 changed files with 56 additions and 51 deletions

View File

@ -32,7 +32,7 @@ class AnnouncementsController < ApplicationController
respond_to do |format|
format.html do
add_crumb(t(:announcements_crumb, "Announcements"))
can_create = @context.announcements.scope.new.grants_right?(@current_user, session, :create)
can_create = @context.announcements.temp_record.grants_right?(@current_user, session, :create)
js_env :permissions => {
:create => can_create,
:moderate => can_create

View File

@ -701,7 +701,7 @@ class ApplicationController < ActionController::Base
if @just_viewing_one_course
# fake assignment used for checking if the @current_user can read unpublished assignments
fake = @context.assignments.scope.new
fake = @context.assignments.temp_record
fake.workflow_state = 'unpublished'
assignment_scope = :active_assignments

View File

@ -80,7 +80,7 @@ class AssignmentGroupsApiController < ApplicationController
#
# @returns AssignmentGroup
def create
@assignment_group = @context.assignment_groups.scope.new
@assignment_group = @context.assignment_groups.temp_record
if authorized_action(@assignment_group, @current_user, :create)
process_assignment_group
end

View File

@ -105,7 +105,7 @@ class AssignmentGroupsController < ApplicationController
#
# @returns [AssignmentGroup]
def index
if authorized_action(@context.assignment_groups.scope.new, @current_user, :read)
if authorized_action(@context.assignment_groups.temp_record, @current_user, :read)
groups = Api.paginate(@context.assignment_groups.active, self, api_v1_course_assignment_groups_url(@context))
assignments = if include_params.include?('assignments')
@ -127,7 +127,7 @@ class AssignmentGroupsController < ApplicationController
end
def reorder
if authorized_action(@context.assignment_groups.scope.new, @current_user, :update)
if authorized_action(@context.assignment_groups.temp_record, @current_user, :update)
order = params[:order].split(',')
@context.assignment_groups.first.update_order(order)
new_order = @context.assignment_groups.pluck(:id)
@ -171,7 +171,7 @@ class AssignmentGroupsController < ApplicationController
end
def create
@assignment_group = @context.assignment_groups.scope.new(params[:assignment_group])
@assignment_group = @context.assignment_groups.temp_record(params[:assignment_group])
if authorized_action(@assignment_group, @current_user, :create)
respond_to do |format|
if @assignment_group.save

View File

@ -360,7 +360,7 @@ class AssignmentsController < ApplicationController
end
def new
@assignment ||= @context.assignments.scope.new
@assignment ||= @context.assignments.temp_record
@assignment.workflow_state = 'unpublished'
add_crumb t :create_new_crumb, "Create new"

View File

@ -45,7 +45,7 @@ class CalendarEventsController < ApplicationController
def new
@event = @context.calendar_events.scope.new
@event = @context.calendar_events.temp_record
add_crumb(t('crumbs.new', "New Calendar Event"), named_context_url(@context, :new_context_calendar_event_url))
@event.assign_attributes(params.slice(:title, :start_at, :end_at, :location_name, :location_address))
js_env(:DIFFERENTIATED_ASSIGNMENTS_ENABLED => @context.feature_enabled?(:differentiated_assignments),

View File

@ -214,7 +214,7 @@ class ConferencesController < ApplicationController
end
def create
if authorized_action(@context.web_conferences.scope.new, @current_user, :create)
if authorized_action(@context.web_conferences.temp_record, @current_user, :create)
params[:web_conference].try(:delete, :long_running)
@conference = @context.web_conferences.build(params[:web_conference])
@conference.settings[:default_return_url] = named_context_url(@context, :context_url, :include_host => true)

View File

@ -514,7 +514,7 @@ class ContextModulesApiController < ApplicationController
#
# @returns Module
def create
if authorized_action(@context.context_modules.scope.new, @current_user, :create)
if authorized_action(@context.context_modules.temp_record, @current_user, :create)
return render :json => {:message => "missing module parameter"}, :status => :bad_request unless params[:module]
return render :json => {:message => "missing module name"}, :status => :bad_request unless params[:module][:name].present?

View File

@ -122,7 +122,7 @@ class ContextModulesController < ApplicationController
end
def create
if authorized_action(@context.context_modules.scope.new, @current_user, :create)
if authorized_action(@context.context_modules.temp_record, @current_user, :create)
@module = @context.context_modules.build
@module.workflow_state = 'unpublished'
@module.attributes = params[:context_module]
@ -139,7 +139,7 @@ class ContextModulesController < ApplicationController
end
def reorder
if authorized_action(@context.context_modules.scope.new, @current_user, :update)
if authorized_action(@context.context_modules.temp_record, @current_user, :update)
m = @context.context_modules.not_deleted.first
m.update_order(params[:order].split(","))

View File

@ -40,7 +40,7 @@ class DiscussionEntriesController < ApplicationController
@topic = @context.discussion_topics.active.find(params[:discussion_entry].delete(:discussion_topic_id))
params[:discussion_entry].delete :remove_attachment rescue nil
parent_id = params[:discussion_entry].delete(:parent_id)
@entry = @topic.discussion_entries.scope.new(params[:discussion_entry])
@entry = @topic.discussion_entries.temp_record(params[:discussion_entry])
@entry.current_user = @current_user
@entry.user_id = @current_user ? @current_user.id : nil
@entry.parent_id = parent_id

View File

@ -268,7 +268,7 @@ class DiscussionTopicsController < ApplicationController
#
# @returns [DiscussionTopic]
def index
return unless authorized_action(@context.discussion_topics.scope.new, @current_user, :read)
return unless authorized_action(@context.discussion_topics.temp_record, @current_user, :read)
return child_topic if is_child_topic?
scope = if params[:only_announcements]
@ -332,7 +332,7 @@ class DiscussionTopicsController < ApplicationController
lockedTopics: locked_topics,
newTopicURL: named_context_url(@context, :new_context_discussion_topic_url),
permissions: {
create: @context.discussion_topics.scope.new.grants_right?(@current_user, session, :create),
create: @context.discussion_topics.temp_record.grants_right?(@current_user, session, :create),
moderate: user_can_moderate,
change_settings: user_can_edit_course_settings?,
manage_content: @context.grants_right?(@current_user, session, :manage_content),
@ -376,7 +376,7 @@ class DiscussionTopicsController < ApplicationController
hash = {
URL_ROOT: named_context_url(@context, :api_v1_context_discussion_topics_url),
PERMISSIONS: {
CAN_CREATE_ASSIGNMENT: @context.respond_to?(:assignments) && @context.assignments.scope.new.grants_right?(@current_user, session, :create),
CAN_CREATE_ASSIGNMENT: @context.respond_to?(:assignments) && @context.assignments.temp_record.grants_right?(@current_user, session, :create),
CAN_ATTACH: @topic.grants_right?(@current_user, session, :attach),
CAN_MODERATE: user_can_moderate
}
@ -799,7 +799,7 @@ class DiscussionTopicsController < ApplicationController
# (For example, "order=104,102,103".)
#
def reorder
if authorized_action(@context.discussion_topics.scope.new, @current_user, :update)
if authorized_action(@context.discussion_topics.temp_record, @current_user, :update)
order = Api.value_to_array(params[:order])
reject! "order parameter required" unless order && order.length > 0
topics = pinned_topics.where(id: order)
@ -843,7 +843,7 @@ class DiscussionTopicsController < ApplicationController
def process_discussion_topic(is_new = false)
@errors = {}
discussion_topic_hash = params.slice(*API_ALLOWED_TOPIC_FIELDS)
model_type = value_to_boolean(discussion_topic_hash.delete(:is_announcement)) && @context.announcements.scope.new.grants_right?(@current_user, session, :create) ? :announcements : :discussion_topics
model_type = value_to_boolean(discussion_topic_hash.delete(:is_announcement)) && @context.announcements.temp_record.grants_right?(@current_user, session, :create) ? :announcements : :discussion_topics
if is_new
@topic = @context.send(model_type).build
else
@ -1092,7 +1092,7 @@ class DiscussionTopicsController < ApplicationController
def handle_assignment_edit_params(hash)
hash[:title] = params[:title] if params[:title]
if params.slice(*[:due_at, :points_possible, :assignment_group_id]).present?
if hash[:assignment].nil? && @context.respond_to?(:assignments) && @context.assignments.scope.new.grants_right?(@current_user, session, :create)
if hash[:assignment].nil? && @context.respond_to?(:assignments) && @context.assignments.temp_record.grants_right?(@current_user, session, :create)
hash[:assignment] ||= {}
end

View File

@ -82,7 +82,7 @@ class ExternalFeedsController < ApplicationController
#
# @returns [ExternalFeed]
def index
if authorized_action(@context.announcements.scope.new, @current_user, :create)
if authorized_action(@context.announcements.temp_record, @current_user, :create)
api_route = polymorphic_url([:api, :v1, @context, :external_feeds])
@feeds = Api.paginate(@context.external_feeds.order(:id), self, api_route)
render :json => external_feeds_api_json(@feeds, @context, @current_user, session)
@ -111,7 +111,7 @@ class ExternalFeedsController < ApplicationController
#
# @returns ExternalFeed
def create
if authorized_action(@context.announcements.scope.new, @current_user, :create)
if authorized_action(@context.announcements.temp_record, @current_user, :create)
@feed = create_api_external_feed(@context, params, @current_user)
if @feed.save
render :json => external_feed_api_json(@feed, @context, @current_user, session)
@ -131,7 +131,7 @@ class ExternalFeedsController < ApplicationController
#
# @returns ExternalFeed
def destroy
if authorized_action(@context.announcements.scope.new, @current_user, :create)
if authorized_action(@context.announcements.temp_record, @current_user, :create)
@feed = @context.external_feeds.find(params[:external_feed_id])
if @feed.destroy
render :json => external_feed_api_json(@feed, @context, @current_user, session)

View File

@ -119,7 +119,7 @@ class FilesController < ApplicationController
def quota
get_quota
if authorized_action(@context.attachments.scope.new, @current_user, :create)
if authorized_action(@context.attachments.temp_record, @current_user, :create)
h = ActionView::Base.new
h.extend ActionView::Helpers::NumberHelper
result = {
@ -305,7 +305,7 @@ class FilesController < ApplicationController
end
def images
if authorized_action(@context.attachments.scope.new, @current_user, :read)
if authorized_action(@context.attachments.temp_record, @current_user, :read)
if Folder.root_folders(@context).first.grants_right?(@current_user, session, :read_contents)
if @context.grants_right?(@current_user, session, :manage_files)
@images = @context.active_images.paginate :page => params[:page]
@ -721,7 +721,7 @@ class FilesController < ApplicationController
@context = @group || @current_user
@check_quota = false
elsif @context && intent == 'attach_discussion_file'
permission_object = @context.discussion_topics.scope.new
permission_object = @context.discussion_topics.temp_record
permission = :attach
elsif @context && intent == 'message'
permission_object = @context

View File

@ -436,7 +436,7 @@ class GroupsController < ApplicationController
attrs = api_request? ? params : params[:group]
attrs.delete :storage_quota_mb unless @context.grants_right? @current_user, session, :manage_storage_quotas
@group = @context.groups.scope.new(attrs.slice(*SETTABLE_GROUP_ATTRIBUTES))
@group = @context.groups.temp_record(attrs.slice(*SETTABLE_GROUP_ATTRIBUTES))
if authorized_action(@group, @current_user, :create)
respond_to do |format|

View File

@ -96,7 +96,7 @@ class QuestionBanksController < ApplicationController
end
def create
if authorized_action(@context.assessment_question_banks.scope.new, @current_user, :create)
if authorized_action(@context.assessment_question_banks.temp_record, @current_user, :create)
@bank = @context.assessment_question_banks.build(params[:assessment_question_bank])
respond_to do |format|
if @bank.save

View File

@ -457,7 +457,7 @@ class Quizzes::QuizzesApiController < ApplicationController
#
# @returns Quiz
def create
if authorized_action(@context.quizzes.scope.new, @current_user, :create)
if authorized_action(@context.quizzes.temp_record, @current_user, :create)
@quiz = @context.quizzes.build
update_api_quiz(@quiz, params)
unless @quiz.new_record?

View File

@ -117,7 +117,7 @@ class Quizzes::QuizzesController < ApplicationController
assignment_overrides: api_v1_course_quiz_assignment_overrides_url(@context)
},
:PERMISSIONS => {
create: can_do(@context.quizzes.scope.new, @current_user, :create),
create: can_do(@context.quizzes.temp_record, @current_user, :create),
manage: can_manage,
read_question_banks: can_manage || can_do(@context, @current_user, :read_question_banks)
},
@ -240,7 +240,7 @@ class Quizzes::QuizzesController < ApplicationController
end
def new
if authorized_action(@context.quizzes.scope.new, @current_user, :create)
if authorized_action(@context.quizzes.temp_record, @current_user, :create)
@assignment = nil
@assignment = @context.assignments.active.find(params[:assignment_id]) if params[:assignment_id]
@quiz = @context.quizzes.build
@ -307,7 +307,7 @@ class Quizzes::QuizzesController < ApplicationController
end
def create
if authorized_action(@context.quizzes.scope.new, @current_user, :create)
if authorized_action(@context.quizzes.temp_record, @current_user, :create)
params[:quiz][:title] = nil if params[:quiz][:title] == "undefined"
params[:quiz][:title] ||= t(:default_title, "New Quiz")
params[:quiz].delete(:points_possible) unless params[:quiz][:quiz_type] == 'graded_survey'

View File

@ -137,7 +137,7 @@ class SectionsController < ApplicationController
#
# @returns Section
def create
if authorized_action(@context.course_sections.scope.new, @current_user, :create)
if authorized_action(@context.course_sections.temp_record, @current_user, :create)
sis_section_id = params[:course_section].try(:delete, :sis_section_id)
can_manage_sis = api_request? && sis_section_id.present? &&
@context.root_account.grants_right?(@current_user, session, :manage_sis)

View File

@ -244,7 +244,7 @@ class CommunicationChannel < ActiveRecord::Base
end
def send_otp!(code)
m = self.messages.scope.new
m = self.messages.temp_record
m.to = self.path
m.body = t :body, "Your Canvas verification code is %{verification_code}", :verification_code => code
Mailer.create_message(m).deliver rescue nil # omg! just ignore delivery failures

View File

@ -2409,7 +2409,7 @@ class Course < ActiveRecord::Base
tabs.delete_if {|t| [TAB_PEOPLE, TAB_OUTCOMES].include?(t[:id]) }
end
unless discussion_topics.scope.new.grants_right?(user, :read)
unless discussion_topics.temp_record.grants_right?(user, :read)
tabs.delete_if { |t| t[:id] == TAB_ANNOUNCEMENTS }
end

View File

@ -65,9 +65,9 @@ module Importers
topic = DiscussionTopic.where(context_type: context.class.to_s, context_id: context.id).
where(['id = ? OR (migration_id IS NOT NULL AND migration_id = ?)', options[:id], options[:migration_id]]).first
topic ||= if options[:type] =~ /announcement/i
context.announcements.scope.new
context.announcements.temp_record
else
context.discussion_topics.scope.new
context.discussion_topics.temp_record
end
topic.saved_by = :migration
topic

View File

@ -81,7 +81,7 @@ class Wiki < ActiveRecord::Base
# return an implicitly created page if a page could not be found
unless page
page = self.wiki_pages.scope.new(:title => url.titleize, :url => url)
page = self.wiki_pages.temp_record(:title => url.titleize, :url => url)
page.wiki = self
end
page

View File

@ -42,7 +42,7 @@
<div class="item-group-container" id="context_modules_sortable_container">
<div id="no_context_modules_message" style="display:none; clear: both;">
<% if can_do(@context.context_modules.scope.new, @current_user, :create) %>
<% if can_do(@context.context_modules.temp_record, @current_user, :create) %>
<%= mt 'help.create', <<TEXT, :button => t('#context_modules.buttons.add_module_first', 'Add a New Module')
Course modules let you organize your assignments, pages, files, etc. into smaller sections or units. Modules could be centered around a theme, focused on a specific topic, or even just grouped chronologically.

View File

@ -455,7 +455,7 @@
</span>
<div class="clear"></div>
</li>
<% if can_do(@context.course_sections.scope.new, @current_user, :create) %>
<% if can_do(@context.course_sections.temp_record, @current_user, :create) %>
<li>
<%= form_for :course_section, :url => context_url(@context, :context_sections_url), :html => {:id => "add_section_form", :class => "form-inline", :style => "margin-top: 20px;"} do |f| %>
<h3><%= f.blabel :name, :course_section_name, :en => "Add a New Section" %></h3>

View File

@ -13,7 +13,7 @@
<% content_for :right_side do %>
<div id="course_show_secondary">
<% @can_manage = can_do(@context, @current_user, :manage) %>
<% @can_create_announcements = @context.announcements.scope.new.grants_right?(@current_user, session, :create) %>
<% @can_create_announcements = @context.announcements.temp_record.grants_right?(@current_user, session, :create) %>
<% if can_do(@context, @current_user, :change_course_state) && (@context.unpublished? || @context.unpublishable?) %>
<div id="course_status" <% unless use_new_styles? %>class="text-center"<% end %>>
<h3>

View File

@ -2,14 +2,14 @@
<% if !@context.is_a?(Account) && @context.root_account.feature_enabled?(:student_groups_next) %>
<% js_env :course_id => @context.id %>
<% js_env :STUDENT_CAN_ORGANIZE_GROUPS_FOR_COURSE => @context.respond_to?(:allow_student_organized_groups) && @context.allow_student_organized_groups && can_do(@context.groups.scope.new, @current_user, :create) %>
<% js_env :STUDENT_CAN_ORGANIZE_GROUPS_FOR_COURSE => @context.respond_to?(:allow_student_organized_groups) && @context.allow_student_organized_groups && can_do(@context.groups.temp_record, @current_user, :create) %>
<% js_bundle :react_groups %>
<% else %>
<% content_for :right_side do %>
<div class="rs-margin-lr rs-margin-top">
<% if @context.respond_to?(:allow_student_organized_groups) && @context.allow_student_organized_groups %>
<% if can_do(@context.groups.scope.new, @current_user, :create) %>
<% if can_do(@context.groups.temp_record, @current_user, :create) %>
<a href="#" class="btn button-sidebar-wide add_group_link icon-add"><%= t 'actions.add', 'Start a New Group' %></a>
<% end %>
<% else %>

View File

@ -20,7 +20,7 @@
</a>
</div>
<% end %>
<% if can_do(@context.announcements.scope.new, @current_user, :create) %>
<% if can_do(@context.announcements.temp_record, @current_user, :create) %>
<div><a href="<%= group_announcements_path(@context) %>#new" class='add'><%= t 'new_announcement', "New Announcement" %></a></div>
<% end %>
<% locals = {:title => t('coming_up', "Coming Up"), :contexts_to_link_to => @context, :upcoming => true, :period => :one_week} %>

View File

@ -983,6 +983,11 @@ ActiveRecord::Associations::CollectionProxy.class_eval do
(load_target && target.respond_to?(name, include_private)) ||
proxy_association.klass.respond_to?(name, include_private)
end
def temp_record(*args)
# creates a record with attributes like a child record but is not added to the collection for autosaving
klass.unscoped.merge(scope).new(*args)
end
end
ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do

View File

@ -258,36 +258,36 @@ describe WebConference do
context "creation rights" do
it "should let teachers create conferences" do
course_with_teacher(:active_all => true)
expect(@course.web_conferences.scope.new.grants_right?(@teacher, :create)).to be_truthy
expect(@course.web_conferences.temp_record.grants_right?(@teacher, :create)).to be_truthy
group(:context => @course)
expect(@group.web_conferences.scope.new.grants_right?(@teacher, :create)).to be_truthy
expect(@group.web_conferences.temp_record.grants_right?(@teacher, :create)).to be_truthy
end
it "should not let teachers create conferences if the permission is disabled" do
course_with_teacher(:active_all => true)
@course.account.role_overrides.create!(:role => teacher_role, :permission => "create_conferences", :enabled => false)
expect(@course.web_conferences.scope.new.grants_right?(@teacher, :create)).to be_falsey
expect(@course.web_conferences.temp_record.grants_right?(@teacher, :create)).to be_falsey
group(:context => @course)
expect(@group.web_conferences.scope.new.grants_right?(@teacher, :create)).to be_falsey
expect(@group.web_conferences.temp_record.grants_right?(@teacher, :create)).to be_falsey
end
it "should let students create conferences" do
course_with_student(:active_all => true)
expect(@course.web_conferences.scope.new.grants_right?(@student, :create)).to be_truthy
expect(@course.web_conferences.temp_record.grants_right?(@student, :create)).to be_truthy
group_with_user(:user => @student, :context => @course)
expect(@group.web_conferences.scope.new.grants_right?(@student, :create)).to be_truthy
expect(@group.web_conferences.temp_record.grants_right?(@student, :create)).to be_truthy
end
it "should not let students create conferences if the permission is disabled" do
course_with_student(:active_all => true)
@course.account.role_overrides.create!(:role => student_role, :permission => "create_conferences", :enabled => false)
expect(@course.web_conferences.scope.new.grants_right?(@student, :create)).to be_falsey
expect(@course.web_conferences.temp_record.grants_right?(@student, :create)).to be_falsey
group_with_user(:user => @student, :context => @course)
expect(@group.web_conferences.scope.new.grants_right?(@student, :create)).to be_falsey
expect(@group.web_conferences.temp_record.grants_right?(@student, :create)).to be_falsey
end
end