From daf749e29693ca49313fd105e72ef88f9f94b877 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 16 May 2019 09:20:06 -0500 Subject: [PATCH 01/50] rails update complete --- Gemfile | 13 +-- Gemfile.lock | 100 +++++++++-------- bin/bundle | 106 +----------------- bin/rails | 2 +- bin/setup | 29 +++-- config/application.rb | 2 +- config/cable.yml | 9 ++ config/environment.rb | 4 +- config/environments/development.rb | 4 + config/environments/test.rb | 9 +- .../application_controller_renderer.rb | 6 + config/initializers/cookies_serializer.rb | 4 +- config/initializers/new_framework_defaults.rb | 23 ++++ config/locales/en.yml | 22 +++- config/puma.rb | 47 ++++++++ config/spring.rb | 6 + 16 files changed, 207 insertions(+), 179 deletions(-) create mode 100644 config/cable.yml create mode 100644 config/initializers/application_controller_renderer.rb create mode 100644 config/initializers/new_framework_defaults.rb create mode 100644 config/puma.rb create mode 100644 config/spring.rb diff --git a/Gemfile b/Gemfile index 8072d24d..78c59cf4 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ git_source(:github) do |repo_name| end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '4.2.11' +gem 'rails', '>= 5.0.0.rc2', '< 5.1' # Bootstrap gem 'bootstrap-sass' @@ -76,9 +76,6 @@ gem 'maruku' # Lev framework gem 'lev' -# Ruby dsl for SQL queries -gem 'squeel' - # Contract management gem 'fine_print' @@ -95,7 +92,7 @@ gem 'mini_magick' # Markdown parsing # Pinned for Rails 4.X -gem 'kramdown', '1.6.0' +gem 'kramdown' # Read Excel xlsx spreadsheet files gem 'roo' @@ -123,7 +120,7 @@ gem 'scout_apm', '~> 3.0.x' # PostgreSQL database # Pinned for rails 4.X -gem 'pg', '~> 0.15' +gem 'pg' # HTTP requests gem 'httparty' @@ -180,11 +177,11 @@ group :development, :test do # Fixture replacement # Pinned for rails 4.X - gem 'factory_bot_rails', '< 5.0.0' + gem 'factory_bot_rails' # Lorem Ipsum # Pinned to avoid 18n problem - gem 'faker', '1.6.6' + gem 'faker' # Database cleaning functionality for tests gem 'database_cleaner' diff --git a/Gemfile.lock b/Gemfile.lock index a7f06a34..8da26f70 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,49 +13,52 @@ GEM specs: action_interceptor (1.1.1) rails (>= 3.1, < 5.0) - actionmailer (4.2.11) - actionpack (= 4.2.11) - actionview (= 4.2.11) - activejob (= 4.2.11) + actioncable (5.0.0.rc2) + actionpack (= 5.0.0.rc2) + nio4r (~> 1.2) + websocket-driver (~> 0.6.1) + actionmailer (5.0.0.rc2) + actionpack (= 5.0.0.rc2) + actionview (= 5.0.0.rc2) + activejob (= 5.0.0.rc2) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.11) - actionview (= 4.2.11) - activesupport (= 4.2.11) - rack (~> 1.6) - rack-test (~> 0.6.2) + actionpack (5.0.0.rc2) + actionview (= 5.0.0.rc2) + activesupport (= 5.0.0.rc2) + rack (~> 2.x) + rack-test (~> 0.6.3) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.11) - activesupport (= 4.2.11) + actionview (5.0.0.rc2) + activesupport (= 5.0.0.rc2) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.3) + rails-html-sanitizer (~> 1.0, >= 1.0.2) active_attr (0.12.0) activemodel (>= 3.0.2, < 6.0) activesupport (>= 3.0.2, < 6.0) - activejob (4.2.11) - activesupport (= 4.2.11) - globalid (>= 0.3.0) - activemodel (4.2.11) - activesupport (= 4.2.11) - builder (~> 3.1) - activerecord (4.2.11) - activemodel (= 4.2.11) - activesupport (= 4.2.11) - arel (~> 6.0) - activesupport (4.2.11) + activejob (5.0.0.rc2) + activesupport (= 5.0.0.rc2) + globalid (>= 0.3.6) + activemodel (5.0.0.rc2) + activesupport (= 5.0.0.rc2) + activerecord (5.0.0.rc2) + activemodel (= 5.0.0.rc2) + activesupport (= 5.0.0.rc2) + arel (~> 7.0) + activesupport (5.0.0.rc2) + concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) - thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) acts_as_votable (0.12.0) addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) apipie-rails (0.5.15) rails (>= 4.1) - arel (6.0.4) + arel (7.1.4) autoprefixer-rails (9.5.0) execjs aws-ses (0.6.0) @@ -221,6 +224,7 @@ GEM mail (2.7.1) mini_mime (>= 0.1.1) maruku (0.7.3) + method_source (0.9.2) mime-types (3.2.2) mime-types-data (~> 3.2015) mime-types-data (3.2018.0812) @@ -235,7 +239,8 @@ GEM multi_xml (0.6.0) multipart-post (2.0.0) nifty-generators (0.4.6) - nokogiri (1.10.2) + nio4r (1.2.1) + nokogiri (1.10.3) mini_portile2 (~> 2.4.0) nokogumbo (2.0.1) nokogiri (~> 1.8, >= 1.8.4) @@ -295,21 +300,22 @@ GEM public_suffix (3.0.3) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) - rack (1.6.11) + rack (2.0.7) rack-test (0.6.3) rack (>= 1.0) railroady (1.5.3) - rails (4.2.11) - actionmailer (= 4.2.11) - actionpack (= 4.2.11) - actionview (= 4.2.11) - activejob (= 4.2.11) - activemodel (= 4.2.11) - activerecord (= 4.2.11) - activesupport (= 4.2.11) + rails (5.0.0.rc2) + actioncable (= 5.0.0.rc2) + actionmailer (= 5.0.0.rc2) + actionpack (= 5.0.0.rc2) + actionview (= 5.0.0.rc2) + activejob (= 5.0.0.rc2) + activemodel (= 5.0.0.rc2) + activerecord (= 5.0.0.rc2) + activesupport (= 5.0.0.rc2) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.11) - sprockets-rails + railties (= 5.0.0.rc2) + sprockets-rails (>= 2.0.0) rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) rails-dom-testing (1.0.9) @@ -323,9 +329,10 @@ GEM ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.4) loofah (~> 2.2, >= 2.2.2) - railties (4.2.11) - actionpack (= 4.2.11) - activesupport (= 4.2.11) + railties (5.0.0.rc2) + actionpack (= 5.0.0.rc2) + activesupport (= 5.0.0.rc2) + method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) raindrops (0.19.0) @@ -474,6 +481,9 @@ GEM activemodel (>= 4.2) debug_inspector railties (>= 4.2) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.3) whenever (0.10.0) chronic (>= 0.6.3) xml-simple (1.1.5) @@ -505,15 +515,15 @@ DEPENDENCIES dotenv-rails eco ejs - factory_bot_rails (< 5.0.0) - faker (= 1.6.6) + factory_bot_rails + faker fine_print fog-aws httparty jquery-rails jquery-ui-rails keyword_search - kramdown (= 1.6.0) + kramdown lev lograge maruku @@ -530,10 +540,10 @@ DEPENDENCIES openstax_rescue_from (~> 3.0.0) openstax_utilities parallel_tests - pg (~> 0.15) + pg quiet_assets railroady - rails (= 4.2.11) + rails (>= 5.0.0.rc2, < 5.1) rails-erd rails-html-sanitizer redis-rails diff --git a/bin/bundle b/bin/bundle index 524dfd3f..66e9889e 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,105 +1,3 @@ #!/usr/bin/env ruby -# frozen_string_literal: true - -# -# This file was generated by Bundler. -# -# The application 'bundle' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "rubygems" - -m = Module.new do - module_function - - def invoked_as_script? - File.expand_path($0) == File.expand_path(__FILE__) - end - - def env_var_version - ENV["BUNDLER_VERSION"] - end - - def cli_arg_version - return unless invoked_as_script? # don't want to hijack other binstubs - return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update` - bundler_version = nil - update_index = nil - ARGV.each_with_index do |a, i| - if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN - bundler_version = a - end - next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/ - bundler_version = $1 || ">= 0.a" - update_index = i - end - bundler_version - end - - def gemfile - gemfile = ENV["BUNDLE_GEMFILE"] - return gemfile if gemfile && !gemfile.empty? - - File.expand_path("../../Gemfile", __FILE__) - end - - def lockfile - lockfile = - case File.basename(gemfile) - when "gems.rb" then gemfile.sub(/\.rb$/, gemfile) - else "#{gemfile}.lock" - end - File.expand_path(lockfile) - end - - def lockfile_version - return unless File.file?(lockfile) - lockfile_contents = File.read(lockfile) - return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/ - Regexp.last_match(1) - end - - def bundler_version - @bundler_version ||= begin - env_var_version || cli_arg_version || - lockfile_version || "#{Gem::Requirement.default}.a" - end - end - - def load_bundler! - ENV["BUNDLE_GEMFILE"] ||= gemfile - - # must dup string for RG < 1.8 compatibility - activate_bundler(bundler_version.dup) - end - - def activate_bundler(bundler_version) - if Gem::Version.correct?(bundler_version) && Gem::Version.new(bundler_version).release < Gem::Version.new("2.0") - bundler_version = "< 2" - end - gem_error = activation_error_handling do - gem "bundler", bundler_version - end - return if gem_error.nil? - require_error = activation_error_handling do - require "bundler/version" - end - return if require_error.nil? && Gem::Requirement.new(bundler_version).satisfied_by?(Gem::Version.new(Bundler::VERSION)) - warn "Activating bundler (#{bundler_version}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_version}'`" - exit 42 - end - - def activation_error_handling - yield - nil - rescue StandardError, LoadError => e - e - end -end - -m.load_bundler! - -if m.invoked_as_script? - load Gem.bin_path("bundler", "bundle") -end +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails index 5191e692..07396602 100755 --- a/bin/rails +++ b/bin/rails @@ -1,4 +1,4 @@ #!/usr/bin/env ruby -APP_PATH = File.expand_path('../../config/application', __FILE__) +APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands' diff --git a/bin/setup b/bin/setup index acdb2c13..e620b4da 100755 --- a/bin/setup +++ b/bin/setup @@ -1,29 +1,34 @@ #!/usr/bin/env ruby require 'pathname' +require 'fileutils' +include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) -Dir.chdir APP_ROOT do +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do # This script is a starting point to setup your application. - # Add necessary setup steps to this file: + # Add necessary setup steps to this file. - puts "== Installing dependencies ==" - system "gem install bundler --conservative" - system "bundle check || bundle install" + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') # puts "\n== Copying sample files ==" - # unless File.exist?("config/database.yml") - # system "cp config/database.yml.sample config/database.yml" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' # end puts "\n== Preparing database ==" - system "bin/rake db:setup" + system! 'bin/rails db:setup' puts "\n== Removing old logs and tempfiles ==" - system "rm -f log/*" - system "rm -rf tmp/cache" + system! 'bin/rails log:clear tmp:clear' puts "\n== Restarting application server ==" - system "touch tmp/restart.txt" + system! 'bin/rails restart' end diff --git a/config/application.rb b/config/application.rb index 6e43167c..bb531be5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,4 +1,4 @@ -require File.expand_path('../boot', __FILE__) +require_relative 'boot' require 'rails/all' diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 00000000..0bbde6f7 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,9 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: redis://localhost:6379/1 diff --git a/config/environment.rb b/config/environment.rb index 31714ec5..1652fe4c 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,5 @@ -# Load the rails application -require File.expand_path('../application', __FILE__) +# Load the Rails application. +require_relative 'application' require 'scout_helper' diff --git a/config/environments/development.rb b/config/environments/development.rb index 3fe13011..2fac2693 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -13,9 +13,13 @@ config.consider_all_requests_local = true config.action_controller.perform_caching = false + config.cache_store = :null_store + # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false + config.action_mailer.perform_caching = false + # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log diff --git a/config/environments/test.rb b/config/environments/test.rb index 37f4d138..32fd8d49 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -12,9 +12,11 @@ # preloads Rails for running tests, you may have to set it to true. config.eager_load = false - # Configure static asset server for tests with Cache-Control for performance. - config.serve_static_files = true - config.static_cache_control = 'public, max-age=3600' + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => 'public, max-age=3600' + } # Show full error reports and disable caching. config.consider_all_requests_local = true @@ -25,6 +27,7 @@ # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + config.action_mailer.perform_caching = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100644 index 00000000..51639b67 --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,6 @@ +# Be sure to restart your server when you modify this file. + +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb index 7a06a89f..5a6a32d3 100644 --- a/config/initializers/cookies_serializer.rb +++ b/config/initializers/cookies_serializer.rb @@ -1,3 +1,5 @@ # Be sure to restart your server when you modify this file. -Rails.application.config.action_dispatch.cookies_serializer = :json \ No newline at end of file +# Specify a serializer for the signed and encrypted cookie jars. +# Valid options are :json, :marshal, and :hybrid. +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb new file mode 100644 index 00000000..f6e72335 --- /dev/null +++ b/config/initializers/new_framework_defaults.rb @@ -0,0 +1,23 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.0 upgrade. +# +# Once upgraded flip defaults one by one to migrate to the new default. +# +# Read the Rails 5.0 release notes for more info on each option. + +# Enable per-form CSRF tokens. Previous versions had false. +Rails.application.config.action_controller.per_form_csrf_tokens = false + +# Enable origin-checking CSRF mitigation. Previous versions had false. +Rails.application.config.action_controller.forgery_protection_origin_check = false + +# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. +# Previous versions had false. +ActiveSupport.to_time_preserves_timezone = false + +# Require `belongs_to` associations by default. Previous versions had false. +Rails.application.config.active_record.belongs_to_required_by_default = false + +# Do not halt callback chains when a callback returns false. Previous versions had true. +ActiveSupport.halt_callback_chains_on_return_false = true diff --git a/config/locales/en.yml b/config/locales/en.yml index 179c14ca..06539571 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,5 +1,23 @@ -# Sample localization file for English. Add more files in this directory for other locales. -# See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. en: hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 00000000..c7f311f8 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,47 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum, this matches the default thread size of Active Record. +# +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests, default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked webserver processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. If you use this option +# you need to make sure to reconnect any threads in the `on_worker_boot` +# block. +# +# preload_app! + +# The code in the `on_worker_boot` will be called if you are using +# clustered mode by specifying a number of `workers`. After each worker +# process is booted this block will be run, if you are using `preload_app!` +# option you will want to use this block to reconnect to any threads +# or connections that may have been created at application boot, Ruby +# cannot share connections between processes. +# +# on_worker_boot do +# ActiveRecord::Base.establish_connection if defined?(ActiveRecord) +# end + +# Allow puma to be restarted by `rails restart` command. +plugin :tmp_restart diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 00000000..c9119b40 --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w( + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +).each { |path| Spring.watch(path) } From 5ae49a7787481f98376bac4818e5944cd2191584 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 16 May 2019 09:21:10 -0500 Subject: [PATCH 02/50] generated new schema --- db/schema.rb | 313 +++++++++++++++++++++------------------------------ 1 file changed, 130 insertions(+), 183 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 0f76af02..1779bca1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,4 +1,3 @@ -# encoding: UTF-8 # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -17,58 +16,54 @@ enable_extension "plpgsql" enable_extension "pgcrypto" enable_extension "citext" + enable_extension "uuid-ossp" create_table "administrators", force: :cascade do |t| t.integer "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_administrators_on_user_id", unique: true, using: :btree end - add_index "administrators", ["user_id"], name: "index_administrators_on_user_id", unique: true, using: :btree - create_table "answers", force: :cascade do |t| t.integer "question_id", null: false t.text "content", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "sort_position", null: false + t.index ["question_id", "sort_position"], name: "index_answers_on_question_id_and_sort_position", unique: true, using: :btree end - add_index "answers", ["question_id", "sort_position"], name: "index_answers_on_question_id_and_sort_position", unique: true, using: :btree - create_table "attachments", force: :cascade do |t| t.integer "parent_id", null: false t.string "parent_type", null: false t.string "asset", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["asset"], name: "index_attachments_on_asset", using: :btree + t.index ["parent_id", "parent_type", "asset"], name: "index_attachments_on_parent_id_and_parent_type_and_asset", unique: true, using: :btree end - add_index "attachments", ["asset"], name: "index_attachments_on_asset", using: :btree - add_index "attachments", ["parent_id", "parent_type", "asset"], name: "index_attachments_on_parent_id_and_parent_type_and_asset", unique: true, using: :btree - create_table "authors", force: :cascade do |t| t.integer "sort_position", null: false t.integer "publication_id", null: false t.integer "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["publication_id", "sort_position"], name: "index_authors_on_publication_id_and_sort_position", unique: true, using: :btree + t.index ["user_id", "publication_id"], name: "index_authors_on_user_id_and_publication_id", unique: true, using: :btree end - add_index "authors", ["publication_id", "sort_position"], name: "index_authors_on_publication_id_and_sort_position", unique: true, using: :btree - add_index "authors", ["user_id", "publication_id"], name: "index_authors_on_user_id_and_publication_id", unique: true, using: :btree - create_table "class_licenses", force: :cascade do |t| t.integer "sort_position", null: false t.integer "license_id", null: false t.string "class_name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["class_name", "sort_position"], name: "index_class_licenses_on_class_name_and_sort_position", unique: true, using: :btree + t.index ["license_id", "class_name"], name: "index_class_licenses_on_license_id_and_class_name", unique: true, using: :btree end - add_index "class_licenses", ["class_name", "sort_position"], name: "index_class_licenses_on_class_name_and_sort_position", unique: true, using: :btree - add_index "class_licenses", ["license_id", "class_name"], name: "index_class_licenses_on_license_id_and_class_name", unique: true, using: :btree - create_table "collaborator_solutions", force: :cascade do |t| t.integer "question_id", null: false t.string "title" @@ -76,32 +71,29 @@ t.text "content", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["question_id"], name: "index_collaborator_solutions_on_question_id", using: :btree + t.index ["solution_type"], name: "index_collaborator_solutions_on_solution_type", using: :btree + t.index ["title"], name: "index_collaborator_solutions_on_title", using: :btree end - add_index "collaborator_solutions", ["question_id"], name: "index_collaborator_solutions_on_question_id", using: :btree - add_index "collaborator_solutions", ["solution_type"], name: "index_collaborator_solutions_on_solution_type", using: :btree - add_index "collaborator_solutions", ["title"], name: "index_collaborator_solutions_on_title", using: :btree - create_table "combo_choice_answers", force: :cascade do |t| t.integer "combo_choice_id", null: false t.integer "answer_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["answer_id", "combo_choice_id"], name: "index_combo_choice_answers_on_answer_id_and_combo_choice_id", unique: true, using: :btree + t.index ["combo_choice_id"], name: "index_combo_choice_answers_on_combo_choice_id", using: :btree end - add_index "combo_choice_answers", ["answer_id", "combo_choice_id"], name: "index_combo_choice_answers_on_answer_id_and_combo_choice_id", unique: true, using: :btree - add_index "combo_choice_answers", ["combo_choice_id"], name: "index_combo_choice_answers_on_combo_choice_id", using: :btree - create_table "combo_choices", force: :cascade do |t| - t.integer "stem_id", null: false - t.decimal "correctness", precision: 3, scale: 2, default: 0.0, null: false + t.integer "stem_id", null: false + t.decimal "correctness", precision: 3, scale: 2, default: "0.0", null: false t.text "feedback" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["stem_id", "correctness"], name: "index_combo_choices_on_stem_id_and_correctness", using: :btree end - add_index "combo_choices", ["stem_id", "correctness"], name: "index_combo_choices_on_stem_id_and_correctness", using: :btree - create_table "commontator_comments", force: :cascade do |t| t.string "creator_type" t.integer "creator_id" @@ -114,24 +106,22 @@ t.integer "cached_votes_down", default: 0 t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["cached_votes_down"], name: "index_commontator_comments_on_cached_votes_down", using: :btree + t.index ["cached_votes_up"], name: "index_commontator_comments_on_cached_votes_up", using: :btree + t.index ["creator_id", "creator_type", "thread_id"], name: "index_commontator_comments_on_c_id_and_c_type_and_t_id", using: :btree + t.index ["thread_id", "created_at"], name: "index_commontator_comments_on_thread_id_and_created_at", using: :btree end - add_index "commontator_comments", ["cached_votes_down"], name: "index_commontator_comments_on_cached_votes_down", using: :btree - add_index "commontator_comments", ["cached_votes_up"], name: "index_commontator_comments_on_cached_votes_up", using: :btree - add_index "commontator_comments", ["creator_id", "creator_type", "thread_id"], name: "index_commontator_comments_on_c_id_and_c_type_and_t_id", using: :btree - add_index "commontator_comments", ["thread_id", "created_at"], name: "index_commontator_comments_on_thread_id_and_created_at", using: :btree - create_table "commontator_subscriptions", force: :cascade do |t| t.string "subscriber_type", null: false t.integer "subscriber_id", null: false t.integer "thread_id", null: false t.datetime "created_at" t.datetime "updated_at" + t.index ["subscriber_id", "subscriber_type", "thread_id"], name: "index_commontator_subscriptions_on_s_id_and_s_type_and_t_id", unique: true, using: :btree + t.index ["thread_id"], name: "index_commontator_subscriptions_on_thread_id", using: :btree end - add_index "commontator_subscriptions", ["subscriber_id", "subscriber_type", "thread_id"], name: "index_commontator_subscriptions_on_s_id_and_s_type_and_t_id", unique: true, using: :btree - add_index "commontator_subscriptions", ["thread_id"], name: "index_commontator_subscriptions_on_thread_id", using: :btree - create_table "commontator_threads", force: :cascade do |t| t.string "commontable_type" t.integer "commontable_id" @@ -140,10 +130,9 @@ t.integer "closer_id" t.datetime "created_at" t.datetime "updated_at" + t.index ["commontable_id", "commontable_type"], name: "index_commontator_threads_on_c_id_and_c_type", unique: true, using: :btree end - add_index "commontator_threads", ["commontable_id", "commontable_type"], name: "index_commontator_threads_on_c_id_and_c_type", unique: true, using: :btree - create_table "community_solutions", force: :cascade do |t| t.integer "question_id", null: false t.string "title" @@ -151,34 +140,31 @@ t.text "content", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["question_id"], name: "index_community_solutions_on_question_id", using: :btree + t.index ["solution_type"], name: "index_community_solutions_on_solution_type", using: :btree + t.index ["title"], name: "index_community_solutions_on_title", using: :btree end - add_index "community_solutions", ["question_id"], name: "index_community_solutions_on_question_id", using: :btree - add_index "community_solutions", ["solution_type"], name: "index_community_solutions_on_solution_type", using: :btree - add_index "community_solutions", ["title"], name: "index_community_solutions_on_title", using: :btree - create_table "copyright_holders", force: :cascade do |t| t.integer "sort_position", null: false t.integer "publication_id", null: false t.integer "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["publication_id", "sort_position"], name: "index_copyright_holders_on_publication_id_and_sort_position", unique: true, using: :btree + t.index ["user_id", "publication_id"], name: "index_copyright_holders_on_user_id_and_publication_id", unique: true, using: :btree end - add_index "copyright_holders", ["publication_id", "sort_position"], name: "index_copyright_holders_on_publication_id_and_sort_position", unique: true, using: :btree - add_index "copyright_holders", ["user_id", "publication_id"], name: "index_copyright_holders_on_user_id_and_publication_id", unique: true, using: :btree - create_table "deputizations", force: :cascade do |t| t.integer "deputizer_id", null: false t.integer "deputy_id", null: false t.string "deputy_type", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["deputizer_id"], name: "index_deputizations_on_deputizer_id", using: :btree + t.index ["deputy_id", "deputy_type", "deputizer_id"], name: "index_deputizations_on_d_id_and_d_type_and_d_id", unique: true, using: :btree end - add_index "deputizations", ["deputizer_id"], name: "index_deputizations_on_deputizer_id", using: :btree - add_index "deputizations", ["deputy_id", "deputy_type", "deputizer_id"], name: "index_deputizations_on_d_id_and_d_type_and_d_id", unique: true, using: :btree - create_table "derivations", force: :cascade do |t| t.integer "sort_position", null: false t.integer "derived_publication_id", null: false @@ -187,22 +173,20 @@ t.datetime "hidden_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["derived_publication_id", "hidden_at"], name: "index_derivations_on_derived_publication_id_and_hidden_at", using: :btree + t.index ["derived_publication_id", "sort_position"], name: "index_derivations_on_derived_publication_id_and_sort_position", unique: true, using: :btree + t.index ["source_publication_id", "derived_publication_id"], name: "index_derivations_on_source_p_id_and_derived_p_id", unique: true, using: :btree end - add_index "derivations", ["derived_publication_id", "hidden_at"], name: "index_derivations_on_derived_publication_id_and_hidden_at", using: :btree - add_index "derivations", ["derived_publication_id", "sort_position"], name: "index_derivations_on_derived_publication_id_and_sort_position", unique: true, using: :btree - add_index "derivations", ["source_publication_id", "derived_publication_id"], name: "index_derivations_on_source_p_id_and_derived_p_id", unique: true, using: :btree - create_table "exercise_tags", force: :cascade do |t| t.integer "exercise_id", null: false t.integer "tag_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["exercise_id", "tag_id"], name: "index_exercise_tags_on_exercise_id_and_tag_id", unique: true, using: :btree + t.index ["tag_id"], name: "index_exercise_tags_on_tag_id", using: :btree end - add_index "exercise_tags", ["exercise_id", "tag_id"], name: "index_exercise_tags_on_exercise_id_and_tag_id", unique: true, using: :btree - add_index "exercise_tags", ["tag_id"], name: "index_exercise_tags_on_tag_id", using: :btree - create_table "exercises", force: :cascade do |t| t.string "title" t.text "stimulus" @@ -212,11 +196,10 @@ t.string "a15k_identifier" t.integer "a15k_version" t.boolean "release_to_a15k" + t.index ["title"], name: "index_exercises_on_title", using: :btree + t.index ["vocab_term_id"], name: "index_exercises_on_vocab_term_id", using: :btree end - add_index "exercises", ["title"], name: "index_exercises_on_title", using: :btree - add_index "exercises", ["vocab_term_id"], name: "index_exercises_on_vocab_term_id", using: :btree - create_table "fine_print_contracts", force: :cascade do |t| t.string "name", null: false t.integer "version" @@ -224,10 +207,9 @@ t.text "content", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["name", "version"], name: "index_fine_print_contracts_on_name_and_version", unique: true, using: :btree end - add_index "fine_print_contracts", ["name", "version"], name: "index_fine_print_contracts_on_name_and_version", unique: true, using: :btree - create_table "fine_print_signatures", force: :cascade do |t| t.integer "contract_id", null: false t.integer "user_id", null: false @@ -235,31 +217,28 @@ t.datetime "created_at" t.datetime "updated_at" t.boolean "is_implicit", default: false, null: false + t.index ["contract_id"], name: "index_fine_print_signatures_on_contract_id", using: :btree + t.index ["user_id", "user_type", "contract_id"], name: "index_fine_print_signatures_on_u_id_and_u_type_and_c_id", unique: true, using: :btree end - add_index "fine_print_signatures", ["contract_id"], name: "index_fine_print_signatures_on_contract_id", using: :btree - add_index "fine_print_signatures", ["user_id", "user_type", "contract_id"], name: "index_fine_print_signatures_on_u_id_and_u_type_and_c_id", unique: true, using: :btree - create_table "hints", force: :cascade do |t| t.integer "sort_position", null: false t.integer "question_id", null: false t.text "content", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["question_id", "sort_position"], name: "index_hints_on_question_id_and_sort_position", unique: true, using: :btree end - add_index "hints", ["question_id", "sort_position"], name: "index_hints_on_question_id_and_sort_position", unique: true, using: :btree - create_table "license_compatibilities", force: :cascade do |t| t.integer "original_license_id", null: false t.integer "combined_license_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["combined_license_id", "original_license_id"], name: "index_license_compatibilities_on_c_l_id_and_o_l_id", unique: true, using: :btree + t.index ["original_license_id"], name: "index_license_compatibilities_on_original_license_id", using: :btree end - add_index "license_compatibilities", ["combined_license_id", "original_license_id"], name: "index_license_compatibilities_on_c_l_id_and_o_l_id", unique: true, using: :btree - add_index "license_compatibilities", ["original_license_id"], name: "index_license_compatibilities_on_original_license_id", using: :btree - create_table "licenses", force: :cascade do |t| t.string "name", null: false t.string "title", null: false @@ -272,93 +251,84 @@ t.boolean "allows_commercial_use", default: true, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["name"], name: "index_licenses_on_name", unique: true, using: :btree + t.index ["title"], name: "index_licenses_on_title", unique: true, using: :btree + t.index ["url"], name: "index_licenses_on_url", unique: true, using: :btree end - add_index "licenses", ["name"], name: "index_licenses_on_name", unique: true, using: :btree - add_index "licenses", ["title"], name: "index_licenses_on_title", unique: true, using: :btree - add_index "licenses", ["url"], name: "index_licenses_on_url", unique: true, using: :btree - create_table "list_editors", force: :cascade do |t| t.integer "editor_id", null: false t.string "editor_type", null: false t.integer "list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["editor_id", "editor_type", "list_id"], name: "index_list_editors_on_editor_id_and_editor_type_and_list_id", unique: true, using: :btree + t.index ["list_id"], name: "index_list_editors_on_list_id", using: :btree end - add_index "list_editors", ["editor_id", "editor_type", "list_id"], name: "index_list_editors_on_editor_id_and_editor_type_and_list_id", unique: true, using: :btree - add_index "list_editors", ["list_id"], name: "index_list_editors_on_list_id", using: :btree - create_table "list_nestings", force: :cascade do |t| t.integer "parent_list_id", null: false t.integer "child_list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["child_list_id"], name: "index_list_nestings_on_child_list_id", unique: true, using: :btree + t.index ["parent_list_id"], name: "index_list_nestings_on_parent_list_id", using: :btree end - add_index "list_nestings", ["child_list_id"], name: "index_list_nestings_on_child_list_id", unique: true, using: :btree - add_index "list_nestings", ["parent_list_id"], name: "index_list_nestings_on_parent_list_id", using: :btree - create_table "list_owners", force: :cascade do |t| t.integer "owner_id", null: false t.string "owner_type", null: false t.integer "list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["list_id"], name: "index_list_owners_on_list_id", using: :btree + t.index ["owner_id", "owner_type", "list_id"], name: "index_list_owners_on_owner_id_and_owner_type_and_list_id", unique: true, using: :btree end - add_index "list_owners", ["list_id"], name: "index_list_owners_on_list_id", using: :btree - add_index "list_owners", ["owner_id", "owner_type", "list_id"], name: "index_list_owners_on_owner_id_and_owner_type_and_list_id", unique: true, using: :btree - create_table "list_publication_groups", force: :cascade do |t| t.integer "sort_position", null: false t.integer "list_id", null: false t.integer "publication_group_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["list_id", "sort_position"], name: "index_list_publication_groups_on_list_id_and_sort_position", unique: true, using: :btree + t.index ["publication_group_id", "list_id"], name: "index_list_publication_groups_on_p_g_id_and_l_id", unique: true, using: :btree end - add_index "list_publication_groups", ["list_id", "sort_position"], name: "index_list_publication_groups_on_list_id_and_sort_position", unique: true, using: :btree - add_index "list_publication_groups", ["publication_group_id", "list_id"], name: "index_list_publication_groups_on_p_g_id_and_l_id", unique: true, using: :btree - create_table "list_readers", force: :cascade do |t| t.integer "reader_id", null: false t.string "reader_type", null: false t.integer "list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["list_id"], name: "index_list_readers_on_list_id", using: :btree + t.index ["reader_id", "reader_type", "list_id"], name: "index_list_readers_on_reader_id_and_reader_type_and_list_id", unique: true, using: :btree end - add_index "list_readers", ["list_id"], name: "index_list_readers_on_list_id", using: :btree - add_index "list_readers", ["reader_id", "reader_type", "list_id"], name: "index_list_readers_on_reader_id_and_reader_type_and_list_id", unique: true, using: :btree - create_table "lists", force: :cascade do |t| t.string "name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["name"], name: "index_lists_on_name", using: :btree end - add_index "lists", ["name"], name: "index_lists_on_name", using: :btree - create_table "logic_variable_values", force: :cascade do |t| t.integer "logic_variable_id", null: false t.integer "seed", null: false t.text "value", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["logic_variable_id", "seed"], name: "index_logic_variable_values_on_logic_variable_id_and_seed", unique: true, using: :btree end - add_index "logic_variable_values", ["logic_variable_id", "seed"], name: "index_logic_variable_values_on_logic_variable_id_and_seed", unique: true, using: :btree - create_table "logic_variables", force: :cascade do |t| t.integer "logic_id", null: false t.string "variable", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["logic_id", "variable"], name: "index_logic_variables_on_logic_id_and_variable", unique: true, using: :btree end - add_index "logic_variables", ["logic_id", "variable"], name: "index_logic_variables_on_logic_id_and_variable", unique: true, using: :btree - create_table "logics", force: :cascade do |t| t.integer "parent_id", null: false t.string "parent_type", null: false @@ -366,10 +336,9 @@ t.text "code", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["parent_id", "parent_type", "language"], name: "index_logics_on_parent_id_and_parent_type_and_language", unique: true, using: :btree end - add_index "logics", ["parent_id", "parent_type", "language"], name: "index_logics_on_parent_id_and_parent_type_and_language", unique: true, using: :btree - create_table "oauth_access_grants", force: :cascade do |t| t.integer "resource_owner_id", null: false t.integer "application_id", null: false @@ -379,10 +348,9 @@ t.datetime "created_at", null: false t.datetime "revoked_at" t.string "scopes" + t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree end - add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree - create_table "oauth_access_tokens", force: :cascade do |t| t.integer "resource_owner_id" t.integer "application_id" @@ -393,12 +361,11 @@ t.datetime "created_at", null: false t.string "scopes" t.string "previous_refresh_token", default: "", null: false + t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree + t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree + t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree end - add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree - add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree - add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree - create_table "oauth_applications", force: :cascade do |t| t.string "name", null: false t.string "uid", null: false @@ -410,11 +377,10 @@ t.integer "owner_id" t.string "owner_type" t.boolean "confidential", default: true, null: false + t.index ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree + t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree end - add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree - add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree - create_table "openstax_accounts_accounts", force: :cascade do |t| t.integer "openstax_uid" t.string "username" @@ -423,58 +389,54 @@ t.string "last_name" t.string "full_name" t.string "title" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "faculty_status", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "faculty_status", default: 0, null: false t.string "salesforce_contact_id" - t.uuid "uuid", default: "gen_random_uuid()", null: false - t.integer "role", default: 0, null: false + t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false + t.integer "role", default: 0, null: false t.citext "support_identifier" t.boolean "is_test" + t.index ["access_token"], name: "index_openstax_accounts_accounts_on_access_token", unique: true, using: :btree + t.index ["faculty_status"], name: "index_openstax_accounts_accounts_on_faculty_status", using: :btree + t.index ["first_name"], name: "index_openstax_accounts_accounts_on_first_name", using: :btree + t.index ["full_name"], name: "index_openstax_accounts_accounts_on_full_name", using: :btree + t.index ["last_name"], name: "index_openstax_accounts_accounts_on_last_name", using: :btree + t.index ["openstax_uid"], name: "index_openstax_accounts_accounts_on_openstax_uid", unique: true, using: :btree + t.index ["role"], name: "index_openstax_accounts_accounts_on_role", using: :btree + t.index ["salesforce_contact_id"], name: "index_openstax_accounts_accounts_on_salesforce_contact_id", using: :btree + t.index ["support_identifier"], name: "index_openstax_accounts_accounts_on_support_identifier", unique: true, using: :btree + t.index ["username"], name: "index_openstax_accounts_accounts_on_username", unique: true, using: :btree + t.index ["uuid"], name: "index_openstax_accounts_accounts_on_uuid", unique: true, using: :btree end - add_index "openstax_accounts_accounts", ["access_token"], name: "index_openstax_accounts_accounts_on_access_token", unique: true, using: :btree - add_index "openstax_accounts_accounts", ["faculty_status"], name: "index_openstax_accounts_accounts_on_faculty_status", using: :btree - add_index "openstax_accounts_accounts", ["first_name"], name: "index_openstax_accounts_accounts_on_first_name", using: :btree - add_index "openstax_accounts_accounts", ["full_name"], name: "index_openstax_accounts_accounts_on_full_name", using: :btree - add_index "openstax_accounts_accounts", ["last_name"], name: "index_openstax_accounts_accounts_on_last_name", using: :btree - add_index "openstax_accounts_accounts", ["openstax_uid"], name: "index_openstax_accounts_accounts_on_openstax_uid", unique: true, using: :btree - add_index "openstax_accounts_accounts", ["role"], name: "index_openstax_accounts_accounts_on_role", using: :btree - add_index "openstax_accounts_accounts", ["salesforce_contact_id"], name: "index_openstax_accounts_accounts_on_salesforce_contact_id", using: :btree - add_index "openstax_accounts_accounts", ["support_identifier"], name: "index_openstax_accounts_accounts_on_support_identifier", unique: true, using: :btree - add_index "openstax_accounts_accounts", ["username"], name: "index_openstax_accounts_accounts_on_username", unique: true, using: :btree - add_index "openstax_accounts_accounts", ["uuid"], name: "index_openstax_accounts_accounts_on_uuid", unique: true, using: :btree - create_table "openstax_accounts_group_members", force: :cascade do |t| t.integer "group_id", null: false t.integer "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_members_on_group_id_and_user_id", unique: true, using: :btree + t.index ["user_id"], name: "index_openstax_accounts_group_members_on_user_id", using: :btree end - add_index "openstax_accounts_group_members", ["group_id", "user_id"], name: "index_openstax_accounts_group_members_on_group_id_and_user_id", unique: true, using: :btree - add_index "openstax_accounts_group_members", ["user_id"], name: "index_openstax_accounts_group_members_on_user_id", using: :btree - create_table "openstax_accounts_group_nestings", force: :cascade do |t| t.integer "member_group_id", null: false t.integer "container_group_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["container_group_id"], name: "index_openstax_accounts_group_nestings_on_container_group_id", using: :btree + t.index ["member_group_id"], name: "index_openstax_accounts_group_nestings_on_member_group_id", unique: true, using: :btree end - add_index "openstax_accounts_group_nestings", ["container_group_id"], name: "index_openstax_accounts_group_nestings_on_container_group_id", using: :btree - add_index "openstax_accounts_group_nestings", ["member_group_id"], name: "index_openstax_accounts_group_nestings_on_member_group_id", unique: true, using: :btree - create_table "openstax_accounts_group_owners", force: :cascade do |t| t.integer "group_id", null: false t.integer "user_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_owners_on_group_id_and_user_id", unique: true, using: :btree + t.index ["user_id"], name: "index_openstax_accounts_group_owners_on_user_id", using: :btree end - add_index "openstax_accounts_group_owners", ["group_id", "user_id"], name: "index_openstax_accounts_group_owners_on_group_id_and_user_id", unique: true, using: :btree - add_index "openstax_accounts_group_owners", ["user_id"], name: "index_openstax_accounts_group_owners_on_user_id", using: :btree - create_table "openstax_accounts_groups", force: :cascade do |t| t.integer "openstax_uid", null: false t.boolean "is_public", default: false, null: false @@ -483,11 +445,10 @@ t.text "cached_supertree_group_ids" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["is_public"], name: "index_openstax_accounts_groups_on_is_public", using: :btree + t.index ["openstax_uid"], name: "index_openstax_accounts_groups_on_openstax_uid", unique: true, using: :btree end - add_index "openstax_accounts_groups", ["is_public"], name: "index_openstax_accounts_groups_on_is_public", using: :btree - add_index "openstax_accounts_groups", ["openstax_uid"], name: "index_openstax_accounts_groups_on_openstax_uid", unique: true, using: :btree - create_table "publication_groups", force: :cascade do |t| t.string "publishable_type", null: false t.integer "number", null: false @@ -497,15 +458,14 @@ t.integer "latest_version", null: false t.integer "latest_published_version" t.string "nickname" + t.index ["id", "latest_published_version"], name: "index_publication_groups_on_id_and_latest_published_version", using: :btree + t.index ["id", "latest_version"], name: "index_publication_groups_on_id_and_latest_version", using: :btree + t.index ["nickname"], name: "index_publication_groups_on_nickname", unique: true, using: :btree + t.index ["number", "publishable_type"], name: "index_publication_groups_on_number_and_publishable_type", unique: true, using: :btree + t.index ["publishable_type"], name: "index_publication_groups_on_publishable_type", using: :btree + t.index ["uuid"], name: "index_publication_groups_on_uuid", unique: true, using: :btree end - add_index "publication_groups", ["id", "latest_published_version"], name: "index_publication_groups_on_id_and_latest_published_version", using: :btree - add_index "publication_groups", ["id", "latest_version"], name: "index_publication_groups_on_id_and_latest_version", using: :btree - add_index "publication_groups", ["nickname"], name: "index_publication_groups_on_nickname", unique: true, using: :btree - add_index "publication_groups", ["number", "publishable_type"], name: "index_publication_groups_on_number_and_publishable_type", unique: true, using: :btree - add_index "publication_groups", ["publishable_type"], name: "index_publication_groups_on_publishable_type", using: :btree - add_index "publication_groups", ["uuid"], name: "index_publication_groups_on_uuid", unique: true, using: :btree - create_table "publications", force: :cascade do |t| t.integer "publishable_id", null: false t.string "publishable_type", null: false @@ -520,27 +480,25 @@ t.datetime "updated_at", null: false t.integer "publication_group_id", null: false t.uuid "uuid", null: false + t.index ["embargoed_until"], name: "index_publications_on_embargoed_until", using: :btree + t.index ["license_id"], name: "index_publications_on_license_id", using: :btree + t.index ["publication_group_id", "version"], name: "index_publications_on_publication_group_id_and_version", using: :btree + t.index ["publishable_id", "publishable_type"], name: "index_publications_on_publishable_id_and_publishable_type", unique: true, using: :btree + t.index ["published_at"], name: "index_publications_on_published_at", using: :btree + t.index ["uuid"], name: "index_publications_on_uuid", unique: true, using: :btree + t.index ["yanked_at"], name: "index_publications_on_yanked_at", using: :btree end - add_index "publications", ["embargoed_until"], name: "index_publications_on_embargoed_until", using: :btree - add_index "publications", ["license_id"], name: "index_publications_on_license_id", using: :btree - add_index "publications", ["publication_group_id", "version"], name: "index_publications_on_publication_group_id_and_version", using: :btree - add_index "publications", ["publishable_id", "publishable_type"], name: "index_publications_on_publishable_id_and_publishable_type", unique: true, using: :btree - add_index "publications", ["published_at"], name: "index_publications_on_published_at", using: :btree - add_index "publications", ["uuid"], name: "index_publications_on_uuid", unique: true, using: :btree - add_index "publications", ["yanked_at"], name: "index_publications_on_yanked_at", using: :btree - create_table "question_dependencies", force: :cascade do |t| t.integer "parent_question_id", null: false t.integer "dependent_question_id", null: false t.boolean "is_optional", default: false, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["dependent_question_id", "parent_question_id"], name: "index_question_dependencies_on_dependent_q_id_and_parent_q_id", unique: true, using: :btree + t.index ["parent_question_id"], name: "index_question_dependencies_on_parent_question_id", using: :btree end - add_index "question_dependencies", ["dependent_question_id", "parent_question_id"], name: "index_question_dependencies_on_dependent_q_id_and_parent_q_id", unique: true, using: :btree - add_index "question_dependencies", ["parent_question_id"], name: "index_question_dependencies_on_parent_question_id", using: :btree - create_table "questions", force: :cascade do |t| t.integer "exercise_id", null: false t.text "stimulus" @@ -548,57 +506,51 @@ t.datetime "updated_at", null: false t.boolean "answer_order_matters", default: false, null: false t.integer "sort_position", null: false + t.index ["exercise_id", "sort_position"], name: "index_questions_on_exercise_id_and_sort_position", unique: true, using: :btree end - add_index "questions", ["exercise_id", "sort_position"], name: "index_questions_on_exercise_id_and_sort_position", unique: true, using: :btree - create_table "stem_answers", force: :cascade do |t| - t.integer "stem_id", null: false - t.integer "answer_id", null: false - t.decimal "correctness", precision: 3, scale: 2, default: 0.0, null: false + t.integer "stem_id", null: false + t.integer "answer_id", null: false + t.decimal "correctness", precision: 3, scale: 2, default: "0.0", null: false t.text "feedback" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["answer_id", "stem_id"], name: "index_stem_answers_on_answer_id_and_stem_id", unique: true, using: :btree + t.index ["stem_id", "correctness"], name: "index_stem_answers_on_stem_id_and_correctness", using: :btree end - add_index "stem_answers", ["answer_id", "stem_id"], name: "index_stem_answers_on_answer_id_and_stem_id", unique: true, using: :btree - add_index "stem_answers", ["stem_id", "correctness"], name: "index_stem_answers_on_stem_id_and_correctness", using: :btree - create_table "stems", force: :cascade do |t| t.integer "question_id", null: false t.text "content", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["question_id"], name: "index_stems_on_question_id", using: :btree end - add_index "stems", ["question_id"], name: "index_stems_on_question_id", using: :btree - create_table "stylings", force: :cascade do |t| t.integer "stylable_id", null: false t.string "stylable_type", null: false t.string "style", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["stylable_id", "stylable_type", "style"], name: "index_stylings_on_stylable_id_and_stylable_type_and_style", unique: true, using: :btree end - add_index "stylings", ["stylable_id", "stylable_type", "style"], name: "index_stylings_on_stylable_id_and_stylable_type_and_style", unique: true, using: :btree - create_table "tags", force: :cascade do |t| t.string "name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["name"], name: "index_tags_on_name", unique: true, using: :btree end - add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree - create_table "trusted_applications", force: :cascade do |t| t.integer "application_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["application_id"], name: "index_trusted_applications_on_application_id", unique: true, using: :btree end - add_index "trusted_applications", ["application_id"], name: "index_trusted_applications_on_application_id", unique: true, using: :btree - create_table "users", force: :cascade do |t| t.integer "account_id", null: false t.datetime "deleted_at" @@ -609,42 +561,38 @@ t.boolean "receive_comment_notifications", default: true, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["account_id"], name: "index_users_on_account_id", unique: true, using: :btree + t.index ["deleted_at"], name: "index_users_on_deleted_at", using: :btree end - add_index "users", ["account_id"], name: "index_users_on_account_id", unique: true, using: :btree - add_index "users", ["deleted_at"], name: "index_users_on_deleted_at", using: :btree - create_table "vocab_distractors", force: :cascade do |t| t.integer "vocab_term_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "distractor_publication_group_id", null: false + t.index ["distractor_publication_group_id"], name: "index_vocab_distractors_on_distractor_publication_group_id", using: :btree + t.index ["vocab_term_id", "distractor_publication_group_id"], name: "index_vocab_distractors_on_v_t_id_and_d_p_g_id", unique: true, using: :btree end - add_index "vocab_distractors", ["distractor_publication_group_id"], name: "index_vocab_distractors_on_distractor_publication_group_id", using: :btree - add_index "vocab_distractors", ["vocab_term_id", "distractor_publication_group_id"], name: "index_vocab_distractors_on_v_t_id_and_d_p_g_id", unique: true, using: :btree - create_table "vocab_term_tags", force: :cascade do |t| t.integer "vocab_term_id" t.integer "tag_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["tag_id"], name: "index_vocab_term_tags_on_tag_id", using: :btree + t.index ["vocab_term_id", "tag_id"], name: "index_vocab_term_tags_on_vocab_term_id_and_tag_id", unique: true, using: :btree end - add_index "vocab_term_tags", ["tag_id"], name: "index_vocab_term_tags_on_tag_id", using: :btree - add_index "vocab_term_tags", ["vocab_term_id", "tag_id"], name: "index_vocab_term_tags_on_vocab_term_id_and_tag_id", unique: true, using: :btree - create_table "vocab_terms", force: :cascade do |t| t.string "name", null: false t.string "definition", default: "", null: false t.string "distractor_literals", default: [], null: false, array: true t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["definition"], name: "index_vocab_terms_on_definition", using: :btree + t.index ["name", "definition"], name: "index_vocab_terms_on_name_and_definition", using: :btree end - add_index "vocab_terms", ["definition"], name: "index_vocab_terms_on_definition", using: :btree - add_index "vocab_terms", ["name", "definition"], name: "index_vocab_terms_on_name_and_definition", using: :btree - create_table "votes", force: :cascade do |t| t.integer "votable_id" t.string "votable_type" @@ -655,11 +603,10 @@ t.integer "vote_weight" t.datetime "created_at" t.datetime "updated_at" + t.index ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope", using: :btree + t.index ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree end - add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope", using: :btree - add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree - add_foreign_key "exercise_tags", "exercises", on_update: :cascade, on_delete: :cascade add_foreign_key "exercise_tags", "tags", on_update: :cascade, on_delete: :cascade add_foreign_key "list_publication_groups", "lists" From 061d0e83a91b5bfe9fbb940068179ac8a0fe4ad8 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 17 May 2019 15:46:10 -0500 Subject: [PATCH 03/50] WIP - tests run! --- Gemfile | 24 +- Gemfile.lock | 305 +++++++++--------- config/application.rb | 2 - config/boot.rb | 3 +- .../application_controller_renderer.rb | 2 + config/initializers/kramdown.rb | 49 --- config/initializers/new_framework_defaults.rb | 4 +- config/initializers/wrap_parameters.rb | 2 +- spec/factories/users.rb | 2 +- 9 files changed, 178 insertions(+), 215 deletions(-) delete mode 100644 config/initializers/kramdown.rb diff --git a/Gemfile b/Gemfile index 78c59cf4..da96fd66 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ git_source(:github) do |repo_name| end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '>= 5.0.0.rc2', '< 5.1' +gem 'rails', '~> 5.0.7.2' # Bootstrap gem 'bootstrap-sass' @@ -62,14 +62,17 @@ gem 'whenever' gem 'omniauth-oauth2', '~> 1.3.1' # OpenStax Accounts integration -gem 'openstax_accounts', '~> 7.12.0' +#gem 'openstax_accounts', '~> 7.12.0' +gem 'openstax_accounts', path: '../accounts-rails' + # Access control for API's gem 'doorkeeper' # API versioning and documentation gem 'representable', '~> 3.0.0' -gem 'openstax_api', '~> 8.3.0' +#gem 'openstax_api', '~> 8.3.0' +gem 'openstax_api', github: 'openstax/openstax_api', branch: 'rails5' gem 'apipie-rails' gem 'maruku' @@ -77,7 +80,8 @@ gem 'maruku' gem 'lev' # Contract management -gem 'fine_print' +#gem 'fine_print' +gem 'fine_print', github: 'lml/fine_print', branch: 'rails5' # Keyword search gem 'keyword_search' @@ -107,7 +111,8 @@ gem 'eco' gem 'deep_cloneable' # Sortable objects -gem 'sortability' +#gem 'sortability' +gem 'sortability', github: 'openstax/sortability', branch: 'rails5' # Comments on objects gem 'commontator' @@ -120,7 +125,7 @@ gem 'scout_apm', '~> 3.0.x' # PostgreSQL database # Pinned for rails 4.X -gem 'pg' +gem 'pg', '~> 0.18' # HTTP requests gem 'httparty' @@ -131,7 +136,8 @@ gem 'a15k_client', branch: 'master' # Notify developers of Exceptions in production -gem 'openstax_rescue_from', '~> 3.0.0' +#gem 'openstax_rescue_from', '~> 3.0.0' +gem 'openstax_rescue_from', github: 'openstax/rescue_from', branch: 'rails5' # Sentry integration (the require disables automatic Rails integration since we use rescue_from) gem 'sentry-raven', require: 'raven/base' @@ -173,7 +179,7 @@ group :development, :test do gem 'rspec-rails' # Mute asset pipeline log messages - gem 'quiet_assets' +# gem 'quiet_assets' # Fixture replacement # Pinned for rails 4.X @@ -221,8 +227,6 @@ group :test do # Codecov integration gem 'codecov', require: false - # Test after-commit hooks - gem 'test_after_commit' end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index 8da26f70..1e05c80d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,49 +8,108 @@ GIT json typhoeus (~> 1.0, >= 1.0.1) +GIT + remote: https://github.com/lml/fine_print.git + revision: 6efd8c8ae1c9800e5cc2b082bd8b467e7df36430 + branch: rails5 + specs: + fine_print (4.0.1) + action_interceptor (>= 1.0) + jquery-rails + rails (>= 4.2) + responders + +GIT + remote: https://github.com/openstax/openstax_api.git + revision: 3068f04b5e96f790284fac02509b3c404f5ff059 + branch: rails5 + specs: + openstax_api (8.3.2) + doorkeeper (>= 2.0) + exception_notification (>= 4.0) + lev (>= 1.0.0) + openstax_utilities (>= 4.2.0) + rails (>= 3.1) + representable (>= 2.4, < 4.0) + responders + roar (>= 1.0) + roar-rails (>= 1.0) + uber (< 0.1.0) + +GIT + remote: https://github.com/openstax/rescue_from.git + revision: 20255f01002b452733cbb66911a7db9d065e2f10 + branch: rails5 + specs: + openstax_rescue_from (3.0.0) + rails (>= 3.1, < 6.0) + +GIT + remote: https://github.com/openstax/sortability.git + revision: 09116898fbab7b07361251891315574259db9d78 + branch: rails5 + specs: + sortability (0.1.0) + rails + +PATH + remote: ../accounts-rails + specs: + openstax_accounts (7.13.1) + action_interceptor (>= 1.0) + keyword_search (>= 1.0.0) + lev (>= 2.2.1) + oauth2 (>= 0.5.0) + omniauth (>= 1.1) + omniauth-oauth2 (>= 1.1) + openstax_api (>= 3.1.0) + openstax_utilities (>= 4.1.0) + rails (>= 4.1) + representable (>= 2.0) + GEM remote: https://rubygems.org/ specs: - action_interceptor (1.1.1) - rails (>= 3.1, < 5.0) - actioncable (5.0.0.rc2) - actionpack (= 5.0.0.rc2) - nio4r (~> 1.2) + action_interceptor (1.1.0) + rails (>= 3.1) + actioncable (5.0.7.2) + actionpack (= 5.0.7.2) + nio4r (>= 1.2, < 3.0) websocket-driver (~> 0.6.1) - actionmailer (5.0.0.rc2) - actionpack (= 5.0.0.rc2) - actionview (= 5.0.0.rc2) - activejob (= 5.0.0.rc2) + actionmailer (5.0.7.2) + actionpack (= 5.0.7.2) + actionview (= 5.0.7.2) + activejob (= 5.0.7.2) mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (5.0.0.rc2) - actionview (= 5.0.0.rc2) - activesupport (= 5.0.0.rc2) - rack (~> 2.x) + rails-dom-testing (~> 2.0) + actionpack (5.0.7.2) + actionview (= 5.0.7.2) + activesupport (= 5.0.7.2) + rack (~> 2.0) rack-test (~> 0.6.3) - rails-dom-testing (~> 1.0, >= 1.0.5) + rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.0.0.rc2) - activesupport (= 5.0.0.rc2) + actionview (5.0.7.2) + activesupport (= 5.0.7.2) builder (~> 3.1) erubis (~> 2.7.0) - rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - active_attr (0.12.0) - activemodel (>= 3.0.2, < 6.0) - activesupport (>= 3.0.2, < 6.0) - activejob (5.0.0.rc2) - activesupport (= 5.0.0.rc2) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + active_attr (0.13.1) + activemodel (>= 3.0.2, < 6.1) + activesupport (>= 3.0.2, < 6.1) + activejob (5.0.7.2) + activesupport (= 5.0.7.2) globalid (>= 0.3.6) - activemodel (5.0.0.rc2) - activesupport (= 5.0.0.rc2) - activerecord (5.0.0.rc2) - activemodel (= 5.0.0.rc2) - activesupport (= 5.0.0.rc2) + activemodel (5.0.7.2) + activesupport (= 5.0.7.2) + activerecord (5.0.7.2) + activemodel (= 5.0.7.2) + activesupport (= 5.0.7.2) arel (~> 7.0) - activesupport (5.0.0.rc2) + activesupport (5.0.7.2) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (~> 0.7) + i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) acts_as_votable (0.12.0) @@ -59,19 +118,18 @@ GEM apipie-rails (0.5.15) rails (>= 4.1) arel (7.1.4) - autoprefixer-rails (9.5.0) + autoprefixer-rails (9.5.1.1) execjs aws-ses (0.6.0) builder mail (> 2.2.5) mime-types xml-simple - baby_squeel (0.3.1) - activerecord (>= 4.0.0) + bindex (0.7.0) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) - brakeman (4.5.0) + brakeman (4.5.1) builder (3.2.3) byebug (11.0.1) carrierwave (1.3.1) @@ -98,9 +156,9 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - commontator (4.11.1) + commontator (5.1.0) jquery-rails - rails (>= 3.1) + rails (>= 5.0) compass (1.0.3) chunky_png (~> 1.2) compass-core (~> 1.0.2) @@ -121,15 +179,14 @@ GEM crass (1.0.4) daemons (1.3.1) database_cleaner (1.7.0) - debug_inspector (0.0.3) declarative (0.0.10) deep_cloneable (2.4.0) activerecord (>= 3.1.0, < 6) diff-lcs (1.3) diffy (3.3.0) docile (1.1.5) - doorkeeper (5.0.2) - railties (>= 4.2) + doorkeeper (5.1.0) + railties (>= 5) dotenv (2.7.2) dotenv-rails (2.7.2) dotenv (= 2.7.2) @@ -147,25 +204,19 @@ GEM exception_notification (4.3.0) actionmailer (>= 4.0, < 6) activesupport (>= 4.0, < 6) - excon (0.62.0) + excon (0.64.0) execjs (2.7.0) - factory_bot (4.11.1) - activesupport (>= 3.0.0) - factory_bot_rails (4.11.1) - factory_bot (~> 4.11.1) - railties (>= 3.0.0) - faker (1.6.6) - i18n (~> 0.5) + factory_bot (5.0.2) + activesupport (>= 4.2.0) + factory_bot_rails (5.0.2) + factory_bot (~> 5.0.2) + railties (>= 4.2.0) + faker (1.9.3) + i18n (>= 0.7) faraday (0.15.4) multipart-post (>= 1.2, < 3) ffi (1.10.0) - fine_print (4.0.1) - action_interceptor (>= 1.0) - baby_squeel - jquery-rails - rails (>= 4.2) - responders - fog-aws (3.4.0) + fog-aws (3.5.0) fog-core (~> 2.1) fog-json (~> 1.1) fog-xml (~> 0.1) @@ -186,10 +237,10 @@ GEM globalid (0.4.2) activesupport (>= 4.2.0) hashie (3.6.0) - httparty (0.16.4) + httparty (0.17.0) mime-types (~> 3.0) multi_xml (>= 0.5.2) - i18n (0.9.5) + i18n (1.6.0) concurrent-ruby (~> 1.0) ipaddress (0.8.3) jquery-rails (4.3.3) @@ -202,7 +253,7 @@ GEM jwt (2.1.0) keyword_search (1.5.0) kgio (2.11.2) - kramdown (1.6.0) + kramdown (2.1.0) lev (9.0.1) actionpack (>= 4.2) active_attr @@ -212,8 +263,8 @@ GEM hashie transaction_isolation transaction_retry - libv8 (6.7.288.46.1) - lograge (0.10.0) + libv8 (7.3.492.27.1) + lograge (0.11.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) @@ -227,19 +278,19 @@ GEM method_source (0.9.2) mime-types (3.2.2) mime-types-data (~> 3.2015) - mime-types-data (3.2018.0812) + mime-types-data (3.2019.0331) mimemagic (0.3.3) mini_magick (4.9.3) mini_mime (1.0.1) mini_portile2 (2.4.0) - mini_racer (0.2.4) - libv8 (>= 6.3) + mini_racer (0.2.6) + libv8 (>= 6.9.411) minitest (5.11.3) multi_json (1.13.1) multi_xml (0.6.0) - multipart-post (2.0.0) + multipart-post (2.1.1) nifty-generators (0.4.6) - nio4r (1.2.1) + nio4r (2.3.1) nokogiri (1.10.3) mini_portile2 (~> 2.4.0) nokogumbo (2.0.1) @@ -250,7 +301,7 @@ GEM multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - oj (3.7.11) + oj (3.7.12) oj_mimic_json (1.0.1) omniauth (1.9.0) hashie (>= 3.4.6, < 3.7.0) @@ -258,80 +309,47 @@ GEM omniauth-oauth2 (1.3.1) oauth2 (~> 1.0) omniauth (~> 1.2) - openstax_accounts (7.12.0) - action_interceptor (>= 1.0) - keyword_search (>= 1.0.0) - lev (>= 2.2.1) - oauth2 (>= 0.5.0) - omniauth (>= 1.1) - omniauth-oauth2 (>= 1.1) - openstax_api (>= 3.1.0) - openstax_utilities (>= 4.1.0) - pg - rails (>= 4.1, < 5.0) - representable (>= 2.0) - roar (>= 1.0) - openstax_api (8.3.2) - doorkeeper (>= 2.0) - exception_notification (>= 4.0) - lev (>= 1.0.0) - openstax_utilities (>= 4.2.0) - rails (>= 3.1, < 5.0) - representable (>= 2.4, < 4.0) - responders - roar (>= 1.0) - roar-rails (>= 1.0) - uber (< 0.1.0) openstax_healthcheck (0.0.3) rails (>= 3.0) - openstax_rescue_from (3.0.0) - rails (>= 3.1, < 6.0) openstax_utilities (4.2.3) keyword_search lev rails (>= 3.1) pager (1.0.1) - parallel (1.16.0) - parallel_tests (2.28.0) + parallel (1.17.0) + parallel_tests (2.29.0) parallel pg (0.21.0) - polyamorous (1.1.0) - activerecord (>= 3.0) public_suffix (3.0.3) - quiet_assets (1.1.0) - railties (>= 3.1, < 5.0) rack (2.0.7) rack-test (0.6.3) rack (>= 1.0) railroady (1.5.3) - rails (5.0.0.rc2) - actioncable (= 5.0.0.rc2) - actionmailer (= 5.0.0.rc2) - actionpack (= 5.0.0.rc2) - actionview (= 5.0.0.rc2) - activejob (= 5.0.0.rc2) - activemodel (= 5.0.0.rc2) - activerecord (= 5.0.0.rc2) - activesupport (= 5.0.0.rc2) - bundler (>= 1.3.0, < 2.0) - railties (= 5.0.0.rc2) + rails (5.0.7.2) + actioncable (= 5.0.7.2) + actionmailer (= 5.0.7.2) + actionpack (= 5.0.7.2) + actionview (= 5.0.7.2) + activejob (= 5.0.7.2) + activemodel (= 5.0.7.2) + activerecord (= 5.0.7.2) + activesupport (= 5.0.7.2) + bundler (>= 1.3.0) + railties (= 5.0.7.2) sprockets-rails (>= 2.0.0) - rails-deprecated_sanitizer (1.0.3) - activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.9) - activesupport (>= 4.2.0, < 5.0) - nokogiri (~> 1.6) - rails-deprecated_sanitizer (>= 1.0.1) - rails-erd (1.5.2) - activerecord (>= 3.2) - activesupport (>= 3.2) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-erd (1.6.0) + activerecord (>= 4.2) + activesupport (>= 4.2) choice (~> 0.2.0) ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.4) loofah (~> 2.2, >= 2.2.2) - railties (5.0.0.rc2) - actionpack (= 5.0.0.rc2) - activesupport (= 5.0.0.rc2) + railties (5.0.7.2) + actionpack (= 5.0.7.2) + activesupport (= 5.0.7.2) method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) @@ -340,7 +358,7 @@ GEM rb-fsevent (0.10.3) rb-inotify (0.10.0) ffi (~> 1.0) - redis (4.1.0) + redis (4.1.1) redis-actionpack (5.0.2) actionpack (>= 4.0, < 6) redis-rack (>= 1, < 3) @@ -366,7 +384,7 @@ GEM responders (2.4.1) actionpack (>= 4.2.0, < 6.0) railties (>= 4.2.0, < 6.0) - rinku (2.0.5) + rinku (2.0.6) roar (1.0.3) representable (>= 2.0.1, <= 3.0.0) roar-rails (1.0.1) @@ -385,7 +403,7 @@ GEM rspec-mocks (~> 3.8.0) rspec-core (3.8.0) rspec-support (~> 3.8.0) - rspec-expectations (3.8.2) + rspec-expectations (3.8.3) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-instafail (1.0.0) @@ -428,9 +446,6 @@ GEM json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) - sortability (0.1.0) - rails - squeel sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -438,12 +453,6 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - squeel (1.2.3) - activerecord (>= 3.0) - activesupport (>= 3.0) - polyamorous (~> 1.1.0) - test_after_commit (1.2.2) - activerecord (>= 3.2, < 5.0) test_xml (0.1.8) diffy (~> 3.0) nokogiri (>= 1.3.2) @@ -470,21 +479,22 @@ GEM uber (0.0.15) uglifier (4.1.20) execjs (>= 0.3.0, < 3) - unicorn (5.5.0) + unicorn (5.5.1) kgio (~> 2.6) raindrops (~> 0.7) unicorn-worker-killer (0.4.4) get_process_mem (~> 0) unicorn (>= 4, < 6) url (0.3.2) - web-console (3.3.0) - activemodel (>= 4.2) - debug_inspector - railties (>= 4.2) + web-console (3.7.0) + actionview (>= 5.0) + activemodel (>= 5.0) + bindex (>= 0.4.0) + railties (>= 5.0) websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) - whenever (0.10.0) + whenever (0.11.0) chronic (>= 0.6.3) xml-simple (1.1.5) @@ -517,7 +527,7 @@ DEPENDENCIES ejs factory_bot_rails faker - fine_print + fine_print! fog-aws httparty jquery-rails @@ -534,16 +544,15 @@ DEPENDENCIES oj oj_mimic_json omniauth-oauth2 (~> 1.3.1) - openstax_accounts (~> 7.12.0) - openstax_api (~> 8.3.0) + openstax_accounts! + openstax_api! openstax_healthcheck - openstax_rescue_from (~> 3.0.0) + openstax_rescue_from! openstax_utilities parallel_tests - pg - quiet_assets + pg (~> 0.18) railroady - rails (>= 5.0.0.rc2, < 5.1) + rails (~> 5.0.7.2) rails-erd rails-html-sanitizer redis-rails @@ -559,9 +568,7 @@ DEPENDENCIES scout_apm (~> 3.0.x) sentry-raven shoulda-matchers - sortability - squeel - test_after_commit + sortability! thin timecop turbolinks diff --git a/config/application.rb b/config/application.rb index bb531be5..839526cc 100644 --- a/config/application.rb +++ b/config/application.rb @@ -24,8 +24,6 @@ class Application < Rails::Application # config.i18n.default_locale = :de ActiveSupport.escape_html_entities_in_json = false - config.active_record.raise_in_transactional_callbacks = true - # Set the default cache store to Redis # This setting cannot be set from an initializer # See https://github.com/rails/rails/issues/10908 diff --git a/config/boot.rb b/config/boot.rb index 5e5f0c1f..128c941b 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,4 +1,3 @@ -# Set up gems listed in the Gemfile. -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb index 51639b67..f5e924a6 100644 --- a/config/initializers/application_controller_renderer.rb +++ b/config/initializers/application_controller_renderer.rb @@ -1,6 +1,8 @@ # Be sure to restart your server when you modify this file. +# ActiveSupport::Reloader.to_prepare do # ApplicationController.renderer.defaults.merge!( # http_host: 'example.org', # https: false # ) +# end diff --git a/config/initializers/kramdown.rb b/config/initializers/kramdown.rb deleted file mode 100644 index e89c60ef..00000000 --- a/config/initializers/kramdown.rb +++ /dev/null @@ -1,49 +0,0 @@ -# https://www.snip2code.com/Snippet/49311/Monkey-patch-for-Kramdown-to-rewrite-rel -require 'addressable/uri' - -Kramdown::Parser::Kramdown.class_exec do - - def add_link_with_attachments(el, href, title, alt_text = nil, ial = nil) - if Addressable::URI.parse(href).relative? && @options[:attachable] - # href is actually a path to a local file for the spreadsheet importer - outputs = AttachFile.call(attachable: @options[:attachable], file: href).outputs - href = outputs.large_url || outputs.url - end - - add_link_without_attachments(el, href, title, alt_text, ial) - end - alias_method_chain :add_link, :attachments - - SINGLE_DOLLAR_INLINE_MATH_START = /(?" : el.value) - text.gsub!(/<\/?script>?/, '') - - preview = preview_string(converter, el, opts) - - attr = {:'data-math' => text} - if type == :block - preview << converter.format_as_block_html('div', attr, text, opts[:indent]) - else - preview << converter.format_as_span_html('span', attr, text) - end - end - -end diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb index f6e72335..cbf423a8 100644 --- a/config/initializers/new_framework_defaults.rb +++ b/config/initializers/new_framework_defaults.rb @@ -4,7 +4,9 @@ # # Once upgraded flip defaults one by one to migrate to the new default. # -# Read the Rails 5.0 release notes for more info on each option. +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +Rails.application.config.action_controller.raise_on_unfiltered_parameters = true # Enable per-form CSRF tokens. Previous versions had false. Rails.application.config.action_controller.per_form_csrf_tokens = false diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index 33725e95..cf733efd 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -5,7 +5,7 @@ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] if respond_to?(:wrap_parameters) + wrap_parameters format: [:json] end # To enable root element in JSON for ActiveRecord objects. diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 98d4ead8..79dad655 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -7,7 +7,7 @@ first_name { Faker::Name.first_name } last_name { Faker::Name.last_name } full_name { "#{first_name} #{last_name}" } - title { Faker::Name.title } + title { Faker::Job.title } end after(:build) do |user, evaluator| From 7c8a1d86de0df5c89fb0f14a5819586935732a26 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 20 May 2019 16:26:30 -0500 Subject: [PATCH 04/50] mostly deprecation warning fixes --- Gemfile | 3 +- Gemfile.lock | 32 +++++++------- app/controllers/admin/base_controller.rb | 4 +- app/controllers/admin/users_controller.rb | 2 +- .../api/v1/attachments_controller.rb | 4 +- .../api/v1/community_solutions_controller.rb | 2 +- .../api/v1/exercises_controller.rb | 4 +- .../api/v1/publications_controller.rb | 2 +- .../api/v1/vocab_terms_controller.rb | 4 +- app/controllers/application_controller.rb | 2 +- app/controllers/dev/base_controller.rb | 4 +- app/controllers/static_pages_controller.rb | 2 +- app/controllers/webview_controller.rb | 2 +- app/models/administrator.rb | 2 +- app/models/attachment.rb | 8 ++-- app/models/vocab_term.rb | 6 ++- app/routines/search_exercises.rb | 4 +- app/routines/search_vocab_terms.rb | 4 +- ..._to_accounts_accounts.openstax_accounts.rb | 7 +++ db/schema.rb | 7 +-- lib/user_html.rb | 2 +- .../admin/administrators_controller_spec.rb | 12 ++--- .../admin/console_controller_spec.rb | 6 +-- .../admin/exceptions_controller_spec.rb | 6 +-- .../api/v1/attachments_controller_spec.rb | 6 +-- .../api/v1/exercises_controller_spec.rb | 44 +++++++++---------- .../api/v1/publications_controller_spec.rb | 12 ++--- .../api/v1/users_controller_spec.rb | 18 ++++---- .../api/v1/vocab_terms_controller_spec.rb | 38 ++++++++-------- .../oauth/applications_controller_spec.rb | 44 +++++++++---------- spec/models/publication_spec.rb | 2 +- spec/rails_helper.rb | 3 -- spec/support/ruby_2_6_rails_4_2_patch.rb | 14 ------ 33 files changed, 153 insertions(+), 159 deletions(-) create mode 100644 db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb delete mode 100644 spec/support/ruby_2_6_rails_4_2_patch.rb diff --git a/Gemfile b/Gemfile index da96fd66..6fe058c5 100644 --- a/Gemfile +++ b/Gemfile @@ -72,7 +72,8 @@ gem 'doorkeeper' # API versioning and documentation gem 'representable', '~> 3.0.0' #gem 'openstax_api', '~> 8.3.0' -gem 'openstax_api', github: 'openstax/openstax_api', branch: 'rails5' +#gem 'openstax_api', github: 'openstax/openstax_api', branch: 'rails5' +gem 'openstax_api', path: '../openstax_api' gem 'apipie-rails' gem 'maruku' diff --git a/Gemfile.lock b/Gemfile.lock index 1e05c80d..d2f6b045 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,23 +19,6 @@ GIT rails (>= 4.2) responders -GIT - remote: https://github.com/openstax/openstax_api.git - revision: 3068f04b5e96f790284fac02509b3c404f5ff059 - branch: rails5 - specs: - openstax_api (8.3.2) - doorkeeper (>= 2.0) - exception_notification (>= 4.0) - lev (>= 1.0.0) - openstax_utilities (>= 4.2.0) - rails (>= 3.1) - representable (>= 2.4, < 4.0) - responders - roar (>= 1.0) - roar-rails (>= 1.0) - uber (< 0.1.0) - GIT remote: https://github.com/openstax/rescue_from.git revision: 20255f01002b452733cbb66911a7db9d065e2f10 @@ -67,6 +50,21 @@ PATH rails (>= 4.1) representable (>= 2.0) +PATH + remote: ../openstax_api + specs: + openstax_api (8.3.2) + doorkeeper (>= 2.0) + exception_notification (>= 4.0) + lev (>= 1.0.0) + openstax_utilities (>= 4.2.0) + rails (>= 3.1) + representable (>= 2.4, < 4.0) + responders + roar (>= 1.0) + roar-rails (>= 1.0) + uber (< 0.1.0) + GEM remote: https://rubygems.org/ specs: diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 0f8e972d..516932ec 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -1,8 +1,8 @@ module Admin class BaseController < ApplicationController - skip_before_filter :authenticate_user! if Rails.env.development? - before_filter :authenticate_admin! unless Rails.env.development? + skip_before_action :authenticate_user! if Rails.env.development? + before_action :authenticate_admin! unless Rails.env.development? fine_print_skip :general_terms_of_use, :privacy_policy diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 341bff8f..9a0404dc 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -1,7 +1,7 @@ module Admin class UsersController < BaseController - before_filter :set_user, only: [:show, :edit, :update, :become, :delete, :undelete] + before_action :set_user, only: [:show, :edit, :update, :become, :delete, :undelete] # GET /users def index diff --git a/app/controllers/api/v1/attachments_controller.rb b/app/controllers/api/v1/attachments_controller.rb index 44b76988..2117ca65 100644 --- a/app/controllers/api/v1/attachments_controller.rb +++ b/app/controllers/api/v1/attachments_controller.rb @@ -3,8 +3,8 @@ class AttachmentsController < OpenStax::Api::V1::ApiController include Exercises::Finders - before_filter :find_exercise_or_create_draft, only: [:create] - before_filter :find_exercise, only: [:destroy] + before_action :find_exercise_or_create_draft, only: [:create] + before_action :find_exercise, only: [:destroy] ########## # create # diff --git a/app/controllers/api/v1/community_solutions_controller.rb b/app/controllers/api/v1/community_solutions_controller.rb index 717cabd9..1d3ebe4b 100644 --- a/app/controllers/api/v1/community_solutions_controller.rb +++ b/app/controllers/api/v1/community_solutions_controller.rb @@ -1,7 +1,7 @@ module Api::V1 class CommunitySolutionsController < OpenStax::Api::V1::ApiController - before_filter :get_community_solution, only: [:show, :update, :destroy] + before_action :get_community_solution, only: [:show, :update, :destroy] resource_description do api_versions "v1" diff --git a/app/controllers/api/v1/exercises_controller.rb b/app/controllers/api/v1/exercises_controller.rb index 1872f130..4d4918a9 100644 --- a/app/controllers/api/v1/exercises_controller.rb +++ b/app/controllers/api/v1/exercises_controller.rb @@ -3,8 +3,8 @@ class ExercisesController < OpenStax::Api::V1::ApiController include ::Exercises::Finders - before_filter :find_exercise_or_create_draft, only: [:show, :update] - before_filter :find_exercise, only: [:destroy] + before_action :find_exercise_or_create_draft, only: [:show, :update] + before_action :find_exercise, only: [:destroy] resource_description do api_versions "v1" diff --git a/app/controllers/api/v1/publications_controller.rb b/app/controllers/api/v1/publications_controller.rb index 14a44469..a39fed99 100644 --- a/app/controllers/api/v1/publications_controller.rb +++ b/app/controllers/api/v1/publications_controller.rb @@ -7,7 +7,7 @@ class PublicationsController < OpenStax::Api::V1::ApiController 'VocabTerm' => 'Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter', } - before_filter :get_publishable + before_action :get_publishable resource_description do api_versions "v1" diff --git a/app/controllers/api/v1/vocab_terms_controller.rb b/app/controllers/api/v1/vocab_terms_controller.rb index 33c9aa18..19182b1b 100644 --- a/app/controllers/api/v1/vocab_terms_controller.rb +++ b/app/controllers/api/v1/vocab_terms_controller.rb @@ -1,8 +1,8 @@ module Api::V1 class VocabTermsController < OpenStax::Api::V1::ApiController - before_filter :get_vocab_term_or_create_draft, only: [:show, :update] - before_filter :get_vocab_term, only: :destroy + before_action :get_vocab_term_or_create_draft, only: [:show, :update] + before_action :get_vocab_term, only: :destroy resource_description do api_versions "v1" diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c83f6fb7..207f1ea3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -7,7 +7,7 @@ class ApplicationController < ActionController::Base include Lev::HandleWith - before_filter :authenticate_user!, :valid_user! + before_action :authenticate_user!, :valid_user! fine_print_require :general_terms_of_use, :privacy_policy diff --git a/app/controllers/dev/base_controller.rb b/app/controllers/dev/base_controller.rb index 312de862..12027b9f 100644 --- a/app/controllers/dev/base_controller.rb +++ b/app/controllers/dev/base_controller.rb @@ -4,9 +4,9 @@ module Dev class BaseController < ApplicationController - before_filter :development_or_test! + before_action :development_or_test! - skip_before_filter :authenticate_user! + skip_before_action :authenticate_user! fine_print_skip :general_terms_of_use, :privacy_policy protected diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb index 57f2b1d4..9a911150 100644 --- a/app/controllers/static_pages_controller.rb +++ b/app/controllers/static_pages_controller.rb @@ -2,7 +2,7 @@ class StaticPagesController < ApplicationController respond_to :html - skip_before_filter :authenticate_user!, + skip_before_action :authenticate_user!, only: [:about, :contact, :copyright, :developers, :help, :privacy, :share, :status, :terms] fine_print_skip :general_terms_of_use, :privacy_policy, diff --git a/app/controllers/webview_controller.rb b/app/controllers/webview_controller.rb index 72fa2ba7..3012b842 100644 --- a/app/controllers/webview_controller.rb +++ b/app/controllers/webview_controller.rb @@ -4,7 +4,7 @@ class WebviewController < ApplicationController layout :resolve_layout - skip_before_filter :authenticate_user!, only: :home + skip_before_action :authenticate_user!, only: :home fine_print_skip :general_terms_of_use, :privacy_policy, only: :home def home diff --git a/app/models/administrator.rb b/app/models/administrator.rb index c09bc8a1..4af109bd 100644 --- a/app/models/administrator.rb +++ b/app/models/administrator.rb @@ -2,6 +2,6 @@ class Administrator < ActiveRecord::Base belongs_to :user - validates :user, presence: true, uniqueness: true + validates :user, uniqueness: true end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index cfcaa6cd..6b3e77ee 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -7,7 +7,6 @@ class Attachment < ActiveRecord::Base before_update { raise ActiveRecord::ReadOnlyRecord } # Prevent updates validates :asset, presence: true - validates :parent, presence: true validate :unique_asset def filename @@ -22,9 +21,10 @@ def remove_asset! def unique_asset return if asset.nil? || parent.nil? - return unless Attachment.where {(id != my{id}) & \ - (parent == my{parent}) & \ - (asset == my{asset.identifier})}.exists? + at = Attachment.arel_table + return unless Attachment.where((at[:id] != id) & \ + (at[:parent] == parent) & \ + (at[:asset] == asset.identifier)).exists? errors.add(:asset, 'has already been associated with this resource') false end diff --git a/app/models/vocab_term.rb b/app/models/vocab_term.rb index 0ef599a6..3f99ec71 100644 --- a/app/models/vocab_term.rb +++ b/app/models/vocab_term.rb @@ -122,10 +122,12 @@ def before_publication end def after_publication + vt = VocabTerm.arel_table + pub = Publication.arel_table last_def = VocabTerm.joins(publication: :publication_group) .where(publication: {publication_group: {number: number}}) - .where {id != my{id}} - .order {publication.version.desc} + .where (vt[:id] != id) + .order (vt[:publication] { pub[:version].desc}) .limit(1) .pluck(:definition) return if definition == last_def diff --git a/app/routines/search_exercises.rb b/app/routines/search_exercises.rb index a61c689d..d7d43097 100644 --- a/app/routines/search_exercises.rb +++ b/app/routines/search_exercises.rb @@ -35,6 +35,8 @@ def exec(params = {}, options = {}) run(:search, relation: relation, sortable_fields: SORTABLE_FIELDS, params: params) do |with| with.default_keyword :content + ex = Exercise.arel_table + with.keyword :id do |ids| ids.each do |id| sanitized_ids = to_number_array(id) @@ -149,7 +151,7 @@ def exec(params = {}, options = {}) sanitized_titles = to_string_array(ttl, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_titles.empty? - @items = @items.where { title.like_any sanitized_titles } + @items = @items.where(ex[:title].matches_any(sanitized_titles)) end end diff --git a/app/routines/search_vocab_terms.rb b/app/routines/search_vocab_terms.rb index ae9449b4..5ca85a56 100644 --- a/app/routines/search_vocab_terms.rb +++ b/app/routines/search_vocab_terms.rb @@ -40,7 +40,7 @@ def exec(params = {}, options = {}) sanitized_names = to_string_array(nm, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_names.empty? - @items = @items.where { name.like_any sanitized_names } + @items = @items.where ( name.like_any sanitized_names ) end end @@ -164,7 +164,7 @@ def exec(params = {}, options = {}) sanitized_definitions = to_string_array(df, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_definitions.empty? - @items = @items.where { definition.like_any sanitized_definitions } + @items = @items.where( definition.like_any sanitized_definitions ) end end diff --git a/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb new file mode 100644 index 00000000..1c042203 --- /dev/null +++ b/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb @@ -0,0 +1,7 @@ +# This migration comes from openstax_accounts (originally 13) +class AddSchoolTypeToAccountsAccounts < ActiveRecord::Migration[4.2] + def change + add_column :openstax_accounts_accounts, :school_type, :integer, null: false, default: 0 + add_index :openstax_accounts_accounts, :school_type + end +end diff --git a/db/schema.rb b/db/schema.rb index 1779bca1..3d67dd80 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,13 +10,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190308184133) do +ActiveRecord::Schema.define(version: 20190517204620) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "pgcrypto" enable_extension "citext" - enable_extension "uuid-ossp" create_table "administrators", force: :cascade do |t| t.integer "user_id", null: false @@ -393,10 +392,11 @@ t.datetime "updated_at", null: false t.integer "faculty_status", default: 0, null: false t.string "salesforce_contact_id" - t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false + t.uuid "uuid", default: -> { "gen_random_uuid()" } t.integer "role", default: 0, null: false t.citext "support_identifier" t.boolean "is_test" + t.integer "school_type", default: 0, null: false t.index ["access_token"], name: "index_openstax_accounts_accounts_on_access_token", unique: true, using: :btree t.index ["faculty_status"], name: "index_openstax_accounts_accounts_on_faculty_status", using: :btree t.index ["first_name"], name: "index_openstax_accounts_accounts_on_first_name", using: :btree @@ -405,6 +405,7 @@ t.index ["openstax_uid"], name: "index_openstax_accounts_accounts_on_openstax_uid", unique: true, using: :btree t.index ["role"], name: "index_openstax_accounts_accounts_on_role", using: :btree t.index ["salesforce_contact_id"], name: "index_openstax_accounts_accounts_on_salesforce_contact_id", using: :btree + t.index ["school_type"], name: "index_openstax_accounts_accounts_on_school_type", using: :btree t.index ["support_identifier"], name: "index_openstax_accounts_accounts_on_support_identifier", unique: true, using: :btree t.index ["username"], name: "index_openstax_accounts_accounts_on_username", unique: true, using: :btree t.index ["uuid"], name: "index_openstax_accounts_accounts_on_uuid", unique: true, using: :btree diff --git a/lib/user_html.rb b/lib/user_html.rb index 54e6572a..5768cd89 100644 --- a/lib/user_html.rb +++ b/lib/user_html.rb @@ -10,7 +10,7 @@ module ActiveRecord module Base def user_html(*attributes) attributes.each do |attribute| - filter_name = "link_and_sanitize_#{attribute.to_s}" + filter_name = :"link_and_sanitize_#{attribute.to_s}" class_exec do before_validation filter_name diff --git a/spec/controllers/admin/administrators_controller_spec.rb b/spec/controllers/admin/administrators_controller_spec.rb index e7b6f367..49f4e370 100644 --- a/spec/controllers/admin/administrators_controller_spec.rb +++ b/spec/controllers/admin/administrators_controller_spec.rb @@ -35,7 +35,7 @@ module Admin context 'for anonymous' do it 'redirects to the login page' do - expect{ post :create, valid_params }.not_to change{ Administrator.count } + expect{ post :create, params: valid_params }.not_to change{ Administrator.count } expect(response).to redirect_to(controller.openstax_accounts.login_path) end end @@ -43,14 +43,14 @@ module Admin context 'for non-admins' do it 'raises SecurityTransgression' do controller.sign_in user - expect{ post :create, valid_params }.to raise_error(SecurityTransgression) + expect{ post :create, params: valid_params }.to raise_error(SecurityTransgression) end end context 'for admins' do it 'makes the given user an administrator' do controller.sign_in admin - expect{ post :create, valid_params }.to change{ Administrator.count }.by(1) + expect{ post :create, params: valid_params }.to change{ Administrator.count }.by(1) expect(response).to redirect_to(admin_administrators_path) expect(user.reload.is_administrator?).to eq true end @@ -62,7 +62,7 @@ module Admin context 'for anonymous' do it 'redirects to the login page' do - expect{ delete :destroy, valid_params }.not_to change{ Administrator.count } + expect{ delete :destroy, params: valid_params }.not_to change{ Administrator.count } expect(response).to redirect_to(controller.openstax_accounts.login_path) end end @@ -70,14 +70,14 @@ module Admin context 'for non-admins' do it 'raises SecurityTransgression' do controller.sign_in user - expect{ delete :destroy, valid_params }.to raise_error(SecurityTransgression) + expect{ delete :destroy, params: valid_params }.to raise_error(SecurityTransgression) end end context 'for admins' do it 'deletes the given administrator' do controller.sign_in admin - expect{ delete :destroy, valid_params }.to change{ Administrator.count }.by(-1) + expect{ delete :destroy, params: valid_params }.to change{ Administrator.count }.by(-1) expect(response).to redirect_to(admin_administrators_path) expect(admin.reload.is_administrator?).to eq false end diff --git a/spec/controllers/admin/console_controller_spec.rb b/spec/controllers/admin/console_controller_spec.rb index 57e9cc72..388cd948 100644 --- a/spec/controllers/admin/console_controller_spec.rb +++ b/spec/controllers/admin/console_controller_spec.rb @@ -9,7 +9,7 @@ module Admin describe 'GET index' do context 'for anonymous' do it 'redirects to the login page' do - xhr :get, :index + get :index, xhr: true expect(response).to have_http_status(:forbidden) end end @@ -17,14 +17,14 @@ module Admin context 'for non-admins' do it 'raises SecurityTransgression' do controller.sign_in user - expect{ xhr :get, :index }.to raise_error(SecurityTransgression) + expect{ get :index, xhr: true }.to raise_error(SecurityTransgression) end end context 'for admins' do it 'returns http ok' do controller.sign_in admin - xhr :get, :index + get :index, xhr: true expect(response).to have_http_status(:ok) end end diff --git a/spec/controllers/admin/exceptions_controller_spec.rb b/spec/controllers/admin/exceptions_controller_spec.rb index f70204bb..eade1876 100644 --- a/spec/controllers/admin/exceptions_controller_spec.rb +++ b/spec/controllers/admin/exceptions_controller_spec.rb @@ -21,7 +21,7 @@ module Admin context 'for anonymous' do it 'returns 403 forbidden' do EXCEPTIONS.each do |klass, args| - xhr :get, :show, id: klass.name, args: args + get :show, params: { id: klass.name, args: args }, xhr: true expect(response).to have_http_status(:forbidden) end end @@ -31,7 +31,7 @@ module Admin it 'raises SecurityTransgression' do controller.sign_in user EXCEPTIONS.each do |klass, args| - expect{ xhr :get, :show, id: klass.name, args: args }.to( + expect{ get :show, params: { id: klass.name, args: args }, xhr: true }.to( raise_error(SecurityTransgression) ) end @@ -42,7 +42,7 @@ module Admin it 'raises the given exception' do controller.sign_in admin EXCEPTIONS.each do |klass, args| - expect{ xhr :get, :show, id: klass.name, args: args }.to raise_error(klass) + expect{ get :show, params: { id: klass.name, args: args }, xhr: true }.to raise_error(klass) end end end diff --git a/spec/controllers/api/v1/attachments_controller_spec.rb b/spec/controllers/api/v1/attachments_controller_spec.rb index 3afc0fdd..ed542385 100644 --- a/spec/controllers/api/v1/attachments_controller_spec.rb +++ b/spec/controllers/api/v1/attachments_controller_spec.rb @@ -46,7 +46,7 @@ module Api::V1 it 'attaches a file to an exercise' do expect do - api_post :create, user_token, parameters: { exercise_id: exercise_id, file: image } + api_post :create, user_token, params: { exercise_id: exercise_id, file: image } end.to change{ exercise.attachments.count }.by(1) expect(response).to have_http_status(:success) end @@ -54,7 +54,7 @@ module Api::V1 it 'creates a draft if needed' do exercise.publication.publish.save! expect do - api_post :create, user_token, parameters: { exercise_id: exercise_id, file: image } + api_post :create, user_token, params: { exercise_id: exercise_id, file: image } end.to change{ exercise.publication_group.reload.latest_version }.from(1).to(2) expect(response).to have_http_status(:success) end @@ -68,7 +68,7 @@ module Api::V1 ).outputs[:attachment] expect do - api_delete :destroy, user_token, parameters: { + api_delete :destroy, user_token, params: { exercise_id: exercise_id, filename: attachment.read_attribute(:asset) } end.to change(Attachment, :count).by(-1) diff --git a/spec/controllers/api/v1/exercises_controller_spec.rb b/spec/controllers/api/v1/exercises_controller_spec.rb index afe7f693..ccc59965 100644 --- a/spec/controllers/api/v1/exercises_controller_spec.rb +++ b/spec/controllers/api/v1/exercises_controller_spec.rb @@ -214,7 +214,7 @@ module Api::V1 end it "returns the Exercise requested by group_uuid and version" do - api_get :show, @user_token, parameters: { + api_get :show, @user_token, params: { id: "#{@exercise.group_uuid}@#{@exercise.version}" } expect(response).to have_http_status(:success) @@ -225,7 +225,7 @@ module Api::V1 end it "returns the Exercise requested by uuid" do - api_get :show, @user_token, parameters: { id: @exercise.uuid } + api_get :show, @user_token, params: { id: @exercise.uuid } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @exercise.uuid)) expect(response.body_as_hash[:versions]).to( @@ -234,7 +234,7 @@ module Api::V1 end it "returns the Exercise requested by uid" do - api_get :show, @user_token, parameters: { id: @exercise.uid } + api_get :show, @user_token, params: { id: @exercise.uid } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @exercise.uuid)) expect(response.body_as_hash[:versions]).to( @@ -243,7 +243,7 @@ module Api::V1 end it "returns the latest published Exercise if only the group_uuid is specified" do - api_get :show, @user_token, parameters: { id: @exercise.group_uuid } + api_get :show, @user_token, params: { id: @exercise.group_uuid } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @exercise.uuid)) expect(response.body_as_hash[:versions]).to( @@ -252,7 +252,7 @@ module Api::V1 end it "returns the latest published Exercise if only the number is specified" do - api_get :show, @user_token, parameters: { id: @exercise.number } + api_get :show, @user_token, params: { id: @exercise.number } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @exercise.uuid)) expect(response.body_as_hash[:versions]).to( @@ -261,7 +261,7 @@ module Api::V1 end it "returns the latest draft Exercise if \"group_uuid@draft\" is requested" do - api_get :show, @user_token, parameters: { id: "#{@exercise.group_uuid}@draft" } + api_get :show, @user_token, params: { id: "#{@exercise.group_uuid}@draft" } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @exercise_2.uuid)) expect(response.body_as_hash[:versions]).to( @@ -270,7 +270,7 @@ module Api::V1 end it "returns the latest draft Exercise if \"number@draft\" is requested" do - api_get :show, @user_token, parameters: { id: "#{@exercise.number}@draft" } + api_get :show, @user_token, params: { id: "#{@exercise.number}@draft" } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @exercise_2.uuid)) expect(response.body_as_hash[:versions]).to( @@ -280,7 +280,7 @@ module Api::V1 it "returns the latest version of a Exercise if \"@latest\" is requested" do @exercise_1.publication.update_attributes(version: 1000) - api_get :show, @user_token, parameters: { id: "#{@exercise.number}@latest" } + api_get :show, @user_token, params: { id: "#{@exercise.number}@latest" } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @exercise_1.uuid)) expect(response.body_as_hash[:versions]).to( @@ -293,7 +293,7 @@ module Api::V1 @exercise_2.destroy expect do - api_get :show, @user_token, parameters: { id: "#{@exercise.number}@draft" } + api_get :show, @user_token, params: { id: "#{@exercise.number}@draft" } end.to change{ Exercise.count }.by(1) expect(response).to have_http_status(:success) @@ -317,7 +317,7 @@ module Api::V1 after(:all) { DatabaseCleaner.clean } it "shows solutions for published exercises if the requestor is an app" do - api_get :show, @application_token, parameters: { id: @exercise.uid } + api_get :show, @application_token, params: { id: @exercise.uid } expect(response).to have_http_status(:success) expect(response.body_as_hash[:questions].first[:collaborator_solutions]).not_to be_empty @@ -328,7 +328,7 @@ module Api::V1 end it "shows solutions for published exercises if the requestor is allowed to edit it" do - api_get :show, @user_token, parameters: { id: @exercise.uid } + api_get :show, @user_token, params: { id: @exercise.uid } expect(response).to have_http_status(:success) expect(response.body_as_hash[:questions].first[:collaborator_solutions]).not_to be_empty @@ -341,7 +341,7 @@ module Api::V1 it "hides solutions for published exercises if the requestor is not allowed to edit it" do @exercise.publication.authors.destroy_all - api_get :show, @user_token, parameters: { id: @exercise.uid } + api_get :show, @user_token, params: { id: @exercise.uid } expect(response).to have_http_status(:success) expect(response.body_as_hash[:questions].first['collaborator_solutions']).to be_nil @@ -352,7 +352,7 @@ module Api::V1 end it "includes versions of the exercise" do - api_get :show, @user_token, parameters: { id: @exercise.uid } + api_get :show, @user_token, params: { id: @exercise.uid } expect(response).to have_http_status(:success) expect(response.body_as_hash[:versions]).to( eq([@exercise_2.version, @exercise_1.version, @exercise.version]) @@ -375,7 +375,7 @@ module Api::V1 it "creates the requested Exercise and assigns the user as author and CR holder" do expect do - api_post :create, @user_token, raw_post_data: Api::V1::Exercises::Representer.new( + api_post :create, @user_token, body: Api::V1::Exercises::Representer.new( @exercise ).to_hash(user_options: { user: @user }) end.to change { Exercise.count }.by(1) @@ -412,7 +412,7 @@ module Api::V1 ) expect do - api_post :create, @user_token, raw_post_data: Api::V1::Exercises::Representer.new( + api_post :create, @user_token, body: Api::V1::Exercises::Representer.new( exercise ).to_hash(user_options: { user: @user }) end.to change { Exercise.count }.by(1) @@ -427,7 +427,7 @@ module Api::V1 FactoryBot.create :publication_group, nickname: 'MyExercise' expect do - api_post :create, @user_token, raw_post_data: Api::V1::Exercises::Representer.new( + api_post :create, @user_token, body: Api::V1::Exercises::Representer.new( @exercise ).to_hash(user_options: { user: @user }) end.not_to change { Exercise.count } @@ -442,7 +442,7 @@ module Api::V1 before { @old_attributes = @exercise.reload.attributes } it "updates the requested Exercise" do - api_patch :update, @user_token, parameters: { id: @exercise.uid }, raw_post_data: { + api_patch :update, @user_token, params: { id: @exercise.uid }, body: { nickname: 'MyExercise', title: "Ipsum lorem" } expect(response).to have_http_status(:success) @@ -459,7 +459,7 @@ module Api::V1 @exercise.publication.publish.save! expect do - api_patch :update, @user_token, parameters: { id: @exercise.uid }, raw_post_data: { + api_patch :update, @user_token, params: { id: @exercise.uid }, body: { nickname: 'MyExercise', title: "Ipsum lorem" } end.to raise_error(SecurityTransgression) @@ -471,7 +471,7 @@ module Api::V1 it "fails if the nickname has already been taken" do FactoryBot.create :publication_group, nickname: 'MyExercise2' - api_patch :update, @user_token, parameters: { id: @exercise.uid }, raw_post_data: { + api_patch :update, @user_token, params: { id: @exercise.uid }, body: { nickname: 'MyExercise2', title: "Ipsum lorem" } @@ -489,7 +489,7 @@ module Api::V1 exercise_2.reload id = "#{@exercise.number}@draft" - api_patch :update, @user_token, parameters: { id: id }, raw_post_data: { + api_patch :update, @user_token, params: { id: id }, body: { nickname: 'MyExercise', title: "Ipsum lorem" } expect(response).to have_http_status(:success) @@ -512,7 +512,7 @@ module Api::V1 id = "#{@exercise.number}@draft" expect do - api_patch :update, @user_token, parameters: { id: id }, raw_post_data: { + api_patch :update, @user_token, params: { id: id }, body: { nickname: 'MyExercise', title: "Ipsum lorem" } end.to change{ Exercise.count }.by(1) @@ -538,7 +538,7 @@ module Api::V1 context "DELETE destroy" do it "deletes the requested draft Exercise" do expect do - api_delete :destroy, @user_token, parameters: { id: @exercise.uid } + api_delete :destroy, @user_token, params: { id: @exercise.uid } end.to change(Exercise, :count).by(-1) expect(response).to have_http_status(:success) expect(Exercise.where(id: @exercise.id)).not_to exist diff --git a/spec/controllers/api/v1/publications_controller_spec.rb b/spec/controllers/api/v1/publications_controller_spec.rb index 11a38744..8254bc34 100644 --- a/spec/controllers/api/v1/publications_controller_spec.rb +++ b/spec/controllers/api/v1/publications_controller_spec.rb @@ -36,7 +36,7 @@ module Api::V1 expect(exercise.reload.is_published?).to eq false api_put :publish, exercise_author_token, - parameters: { exercise_id: exercise.uid.to_s } + params: { exercise_id: exercise.uid.to_s } expected_response = Api::V1::Exercises::Representer .new(exercise.reload) @@ -54,7 +54,7 @@ module Api::V1 end api_put :publish, exercise_author_token, - parameters: { exercise_id: exercise.uid.to_s } + params: { exercise_id: exercise.uid.to_s } expected_response = { errors: [{ code: 'exercise_has_a_question_with_only_incorrect_answers', @@ -72,7 +72,7 @@ module Api::V1 expect(vocab_term.reload.is_published?).to eq false api_put :publish, vocab_term_author_token, - parameters: { vocab_term_id: vocab_term.uid.to_s } + params: { vocab_term_id: vocab_term.uid.to_s } expected_response = \ Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter.new(vocab_term.reload) @@ -88,7 +88,7 @@ module Api::V1 vocab_term.vocab_distractors.delete_all api_put :publish, vocab_term_author_token, - parameters: { vocab_term_id: vocab_term.uid.to_s } + params: { vocab_term_id: vocab_term.uid.to_s } expected_response = { errors: [{ code: 'vocab_term_must_have_at_least_1_distractor', @@ -105,7 +105,7 @@ module Api::V1 it "publishes the requested community solution" do expect(solution.reload.is_published?).to eq false - api_put :publish, solution_author_token, parameters: { + api_put :publish, solution_author_token, params: { community_solution_id: solution.uid.to_s } @@ -124,7 +124,7 @@ module Api::V1 expect{ api_put :publish, exercise_author_token, - parameters: { exercise_id: exercise.uid.to_s, + params: { exercise_id: exercise.uid.to_s, vocab_term_id: vocab_term.uid.to_s, community_solution_id: solution.uid.to_s } }.to raise_error(ActionController::BadRequest) diff --git a/spec/controllers/api/v1/users_controller_spec.rb b/spec/controllers/api/v1/users_controller_spec.rb index e46fd998..afbe4171 100644 --- a/spec/controllers/api/v1/users_controller_spec.rb +++ b/spec/controllers/api/v1/users_controller_spec.rb @@ -43,7 +43,7 @@ module Api::V1 end it "returns no results if the maximum number of results is exceeded" do - api_get :index, admin_token, parameters: {q: ''} + api_get :index, admin_token, params: {q: ''} expect(response).to have_http_status(:success) expected_response = { @@ -55,7 +55,7 @@ module Api::V1 end it "returns single results" do - api_get :index, application_token, parameters: { q: 'first_name:jOhN last_name:dOe' } + api_get :index, application_token, params: { q: 'first_name:jOhN last_name:dOe' } expect(response).to have_http_status(:success) expected_response = { @@ -81,7 +81,7 @@ module Api::V1 end it "returns multiple results" do - api_get :index, user_token, parameters: {q: 'last_name:DoE'} + api_get :index, user_token, params: {q: 'last_name:DoE'} expect(response).to have_http_status(:success) expected_response = { @@ -120,7 +120,7 @@ module Api::V1 end it "sorts by multiple fields in different directions" do - api_get :index, user_token, parameters: {q: 'username:doe', + api_get :index, user_token, params: {q: 'username:doe', order_by: "first_name DESC, last_name"} expect(response).to have_http_status(:success) @@ -184,7 +184,7 @@ module Api::V1 end it "ignores id parameters" do - api_get :show, user_token, parameters: {id: admin.id, user_id: admin.id} + api_get :show, user_token, params: {id: admin.id, user_id: admin.id} expect(response).to have_http_status(:success) expected_response = { @@ -208,7 +208,7 @@ module Api::V1 context "PATCH update" do it "updates the current User's profile" do - api_patch :update, user_token, raw_post_data: { + api_patch :update, user_token, body: { first_name: "Jerry", last_name: "Mouse" } expect(response).to have_http_status(:success) @@ -218,9 +218,9 @@ module Api::V1 end it "ignores id parameters" do - api_patch :update, user_token, raw_post_data: { + api_patch :update, user_token, body: { first_name: "Jerry", last_name: "Mouse" - }, parameters: {id: admin.id, user_id: admin.id} + }, params: {id: admin.id, user_id: admin.id} expect(response).to have_http_status(:success) user.reload admin.reload @@ -242,7 +242,7 @@ module Api::V1 end it "ignores id parameters" do - api_delete :destroy, user_token, parameters: {id: admin.id, user_id: admin.id} + api_delete :destroy, user_token, params: {id: admin.id, user_id: admin.id} expect(response).to have_http_status(:success) user.reload admin.reload diff --git a/spec/controllers/api/v1/vocab_terms_controller_spec.rb b/spec/controllers/api/v1/vocab_terms_controller_spec.rb index b3582b9e..4cc6934c 100644 --- a/spec/controllers/api/v1/vocab_terms_controller_spec.rb +++ b/spec/controllers/api/v1/vocab_terms_controller_spec.rb @@ -189,7 +189,7 @@ module Api::V1 after(:all) { DatabaseCleaner.clean } it "returns the VocabTerm requested by group_uuid and version" do - api_get :show, @user_token, parameters: { + api_get :show, @user_token, params: { id: "#{@vocab_term.group_uuid}@#{@vocab_term.version}" } expect(response).to have_http_status(:success) @@ -197,37 +197,37 @@ module Api::V1 end it "returns the VocabTerm requested by uuid" do - api_get :show, @user_token, parameters: { id: @vocab_term.uuid } + api_get :show, @user_token, params: { id: @vocab_term.uuid } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @vocab_term.uuid)) end it "returns the VocabTerm requested by uid" do - api_get :show, @user_token, parameters: { id: @vocab_term.uid } + api_get :show, @user_token, params: { id: @vocab_term.uid } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @vocab_term.uuid)) end it "returns the latest published VocabTerm if only the group_uuid is specified" do - api_get :show, @user_token, parameters: { id: @vocab_term.group_uuid } + api_get :show, @user_token, params: { id: @vocab_term.group_uuid } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @vocab_term.uuid)) end it "returns the latest published VocabTerm if only the number is specified" do - api_get :show, @user_token, parameters: { id: @vocab_term.number } + api_get :show, @user_token, params: { id: @vocab_term.number } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @vocab_term.uuid)) end it "returns the latest draft VocabTerm if \"group_uuid@draft\" is requested" do - api_get :show, @user_token, parameters: { id: "#{@vocab_term.group_uuid}@draft" } + api_get :show, @user_token, params: { id: "#{@vocab_term.group_uuid}@draft" } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @vocab_term_2.uuid)) end it "returns the latest draft VocabTerm if \"number@draft\" is requested" do - api_get :show, @user_token, parameters: { id: "#{@vocab_term.number}@draft" } + api_get :show, @user_token, params: { id: "#{@vocab_term.number}@draft" } expect(response).to have_http_status(:success) expect(response.body_as_hash).to match(a_hash_including(uuid: @vocab_term_2.uuid)) end @@ -236,7 +236,7 @@ module Api::V1 @vocab_term_2.destroy expect do - api_get :show, @user_token, parameters: { id: "#{@vocab_term.number}@draft" } + api_get :show, @user_token, params: { id: "#{@vocab_term.number}@draft" } end.to change{ VocabTerm.count }.by(1) expect(response).to have_http_status(:success) @@ -265,7 +265,7 @@ module Api::V1 it "creates the requested VocabTerm and assigns the user as author and CR holder" do expect do api_post :create, @user_token, - raw_post_data: Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter.new( + body: Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter.new( @vocab_term ).to_hash(user_options: { user: @user }) end.to change { VocabTerm.count }.by(1) @@ -285,7 +285,7 @@ module Api::V1 expect do api_post :create, @user_token, - raw_post_data: Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter.new( + body: Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter.new( @vocab_term ).to_hash(user_options: { user: @user }) end.not_to change { VocabTerm.count } @@ -299,8 +299,8 @@ module Api::V1 before { @old_attributes = @vocab_term.reload.attributes } it "updates the requested VocabTerm" do - api_patch :update, @user_token, parameters: { id: @vocab_term.uid }, - raw_post_data: { nickname: 'MyVocab', term: "Ipsum lorem" } + api_patch :update, @user_token, params: { id: @vocab_term.uid }, + body: { nickname: 'MyVocab', term: "Ipsum lorem" } expect(response).to have_http_status(:success) @vocab_term.reload new_attributes = @vocab_term.attributes @@ -315,7 +315,7 @@ module Api::V1 @vocab_term.publication.publish.save! expect do - api_patch :update, @user_token, parameters: { id: @vocab_term.uid }, raw_post_data: { + api_patch :update, @user_token, params: { id: @vocab_term.uid }, body: { nickname: 'MyVocab', term: "Ipsum lorem" } end.to raise_error(SecurityTransgression) @@ -329,7 +329,7 @@ module Api::V1 it "fails if the nickname has already been taken" do FactoryBot.create :publication_group, nickname: 'MyVocab2' - api_patch :update, @user_token, parameters: { id: @vocab_term.uid }, raw_post_data: { + api_patch :update, @user_token, params: { id: @vocab_term.uid }, body: { nickname: 'MyVocab2', title: "Ipsum lorem" } @@ -348,8 +348,8 @@ module Api::V1 vocab_term_2.save! vocab_term_2.reload - api_patch :update, @user_token, parameters: { id: "#{@vocab_term.number}@draft" }, - raw_post_data: { nickname: 'MyVocab', term: "Ipsum lorem" } + api_patch :update, @user_token, params: { id: "#{@vocab_term.number}@draft" }, + body: { nickname: 'MyVocab', term: "Ipsum lorem" } expect(response).to have_http_status(:success) @vocab_term.reload @@ -371,8 +371,8 @@ module Api::V1 @vocab_term.publication.publish.save! expect do - api_patch :update, @user_token, parameters: { id: "#{@vocab_term.number}@draft" }, - raw_post_data: { + api_patch :update, @user_token, params: { id: "#{@vocab_term.number}@draft" }, + body: { nickname: 'MyVocab', term: "Ipsum lorem" } end.to change{ VocabTerm.count }.by(1) @@ -400,7 +400,7 @@ module Api::V1 context "DELETE destroy" do it "deletes the requested draft VocabTerm" do expect do - api_delete :destroy, @user_token, parameters: { id: @vocab_term.uid } + api_delete :destroy, @user_token, params: { id: @vocab_term.uid } end.to change(VocabTerm, :count).by(-1) expect(response).to have_http_status(:success) expect(VocabTerm.where(id: @vocab_term.id)).not_to exist diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb index 1f63244e..d406ccbb 100644 --- a/spec/controllers/oauth/applications_controller_spec.rb +++ b/spec/controllers/oauth/applications_controller_spec.rb @@ -34,7 +34,7 @@ module Oauth context "GET index" do it "assigns the user's applications as @applications" do - get :index, {}, valid_session + get :index, session: valid_session expect(response.code).to eq('200') expect(assigns :applications).to include(group_1_application_1) expect(assigns :applications).to include(group_1_application_2) @@ -43,7 +43,7 @@ module Oauth end it "assigns all applications as @applications for admins" do - get :index, {}, admin_session + get :index, session: admin_session expect(response.code).to eq('200') expect(assigns :applications).to include(group_1_application_1) expect(assigns :applications).to include(group_1_application_2) @@ -54,21 +54,21 @@ module Oauth context "GET show" do it "assigns the requested application as @application" do - get :show, {id: group_1_application_1.to_param}, valid_session + get :show, params: {id: group_1_application_1.to_param}, session: valid_session expect(assigns(:application)).to eq(group_1_application_1) end end context "GET new" do it "assigns a new application as @application" do - get :new, {}, admin_session + get :new, session: admin_session expect(assigns(:application)).to be_a_new(Doorkeeper::Application) end end context "GET edit" do it "assigns the requested application as @application" do - get :edit, {id: group_1_application_1.to_param}, valid_session + get :edit, params: {id: group_1_application_1.to_param}, session: valid_session expect(assigns(:application)).to eq(group_1_application_1) end end @@ -79,18 +79,18 @@ module Oauth it "creates a new Application" do expect { - post :create, {doorkeeper_application: valid_attributes}, admin_session + post :create, params: {doorkeeper_application: valid_attributes}, session: admin_session }.to change(Doorkeeper::Application, :count).by(1) end it "assigns a newly created application as @application" do - post :create, {doorkeeper_application: valid_attributes}, admin_session + post :create, params: {doorkeeper_application: valid_attributes}, session: dmin_session expect(assigns(:application)).to be_a(Doorkeeper::Application) expect(assigns(:application)).to be_persisted end it "redirects to the created application" do - post :create, {doorkeeper_application: valid_attributes}, admin_session + post :create, params: {doorkeeper_application: valid_attributes}, session: admin_session expect(response).to redirect_to( oauth_application_url(Doorkeeper::Application.last) ) @@ -100,13 +100,13 @@ module Oauth context "with invalid params" do it "assigns a newly created but unsaved application as @application" do # Trigger the behavior that occurs when invalid params are submitted - post :create, {doorkeeper_application: { "redirect_uri" => "invalid" }}, admin_session + post :create, params: {doorkeeper_application: { "redirect_uri" => "invalid" }}, session: admin_session expect(assigns(:application)).to be_a_new(Doorkeeper::Application) end it "re-renders the 'new' template" do # Trigger the behavior that occurs when invalid params are submitted - post :create, {doorkeeper_application: { "redirect_uri" => "invalid" }}, admin_session + post :create, params: {doorkeeper_application: { "redirect_uri" => "invalid" }}, session: admin_session expect(response).to render_template("new") end end @@ -117,19 +117,19 @@ module Oauth it "updates the requested application" do expect_any_instance_of(Doorkeeper::Application) .to receive(:update_attributes).with({ "name" => "Dummy" }) - patch :update, {id: group_1_application_1.to_param, - doorkeeper_application: { "name" => "Dummy" }}, valid_session + patch :update, params: {id: group_1_application_1.to_param, + doorkeeper_application: { "name" => "Dummy" }}, session: valid_session end it "assigns the requested application as @application" do - patch :update, {id: group_1_application_1.to_param, - doorkeeper_application: { "name" => "Dummy" }}, valid_session + patch :update, params: {id: group_1_application_1.to_param, + doorkeeper_application: { "name" => "Dummy" }}, session: valid_session expect(assigns(:application)).to eq(group_1_application_1) end it "redirects to the application" do - patch :update, {id: group_1_application_1.to_param, - doorkeeper_application: { "name" => "Dummy" }}, valid_session + patch :update, params: {id: group_1_application_1.to_param, + doorkeeper_application: { "name" => "Dummy" }}, session: valid_session expect(response).to redirect_to( oauth_application_url(group_1_application_1) ) @@ -139,15 +139,15 @@ module Oauth context "with invalid params" do it "assigns the application as @application" do # Trigger the behavior that occurs when invalid params are submitted - patch :update, {id: group_1_application_1.to_param, - doorkeeper_application: { "redirect_uri" => "invalid" }}, valid_session + patch :update, params: {id: group_1_application_1.to_param, + doorkeeper_application: { "redirect_uri" => "invalid" }}, session: valid_session expect(assigns(:application)).to eq(group_1_application_1) end it "re-renders the 'edit' template" do # Trigger the behavior that occurs when invalid params are submitted - patch :update, {id: group_1_application_1.to_param, - doorkeeper_application: { "redirect_uri" => "invalid" }}, valid_session + patch :update, params: {id: group_1_application_1.to_param, + doorkeeper_application: { "redirect_uri" => "invalid" }}, session: valid_session expect(response).to render_template("edit") end end @@ -156,12 +156,12 @@ module Oauth context "DELETE destroy" do it "destroys the requested application" do expect { - delete :destroy, {id: group_1_application_1.to_param}, admin_session + delete :destroy, params: {id: group_1_application_1.to_param}, session: admin_session }.to change(Doorkeeper::Application, :count).by(-1) end it "redirects to the applications list" do - delete :destroy, {id: group_1_application_1.to_param}, admin_session + delete :destroy, params: {id: group_1_application_1.to_param}, session: admin_session expect(response).to redirect_to(oauth_applications_url) end end diff --git a/spec/models/publication_spec.rb b/spec/models/publication_spec.rb index 9d1c0cfd..3bd21629 100644 --- a/spec/models/publication_spec.rb +++ b/spec/models/publication_spec.rb @@ -96,7 +96,7 @@ it 'validates the publishable before publication' do expect(publication.reload.publishable).to receive(:before_publication) do publication.publishable.errors.add(:base, 'is invalid') - false + throw :abort end expect(publication.publish.save).to eq false expect(publication.errors.first).to eq [:exercise, 'is invalid'] diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index e2623a92..37ae970a 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -20,9 +20,6 @@ end end -# Remove after dropping support of Rails 4.2 -require "#{File.dirname(__FILE__)}/support/ruby_2_6_rails_4_2_patch" - # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are # run as spec files by default. This means that files in spec/support that end diff --git a/spec/support/ruby_2_6_rails_4_2_patch.rb b/spec/support/ruby_2_6_rails_4_2_patch.rb deleted file mode 100644 index 1e1d9f98..00000000 --- a/spec/support/ruby_2_6_rails_4_2_patch.rb +++ /dev/null @@ -1,14 +0,0 @@ -if RUBY_VERSION >= '2.6.0' - if Rails::VERSION::MAJOR < 5 - class ActionController::TestResponse < ActionDispatch::TestResponse - def recycle! - # hack to avoid MonitorMixin double-initialize error: - @mon_mutex_owner_object_id = nil - @mon_mutex = nil - initialize - end - end - else - puts "Monkeypatch for ActionController::TestResponse no longer needed" - end -end From b3712c0bba01e511c7bc27aef3085d97d9f9de21 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 24 May 2019 09:42:40 -0500 Subject: [PATCH 05/50] remove one patch; add another --- config/environment.rb | 2 +- lib/active_record/calculations_patch.rb | 31 ------------------- .../table_association_name_patch.rb | 23 ++++++++++++++ 3 files changed, 24 insertions(+), 32 deletions(-) delete mode 100644 lib/active_record/calculations_patch.rb create mode 100644 lib/active_record/table_association_name_patch.rb diff --git a/config/environment.rb b/config/environment.rb index 1652fe4c..d928e4d5 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -26,7 +26,7 @@ require 'ar_collection_setter' -require 'active_record/calculations_patch' +require 'active_record/table_association_name_patch' SITE_NAME = "OpenStax Exercises" COPYRIGHT_HOLDER = "Rice University" diff --git a/lib/active_record/calculations_patch.rb b/lib/active_record/calculations_patch.rb deleted file mode 100644 index 3ff7ed95..00000000 --- a/lib/active_record/calculations_patch.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Due to weird interactions between Squeel and ActiveRecord, -# we need this patch to be able to use .count in the exercises search -# Otherwise, the grep method call will throw an exception and the count will fail -# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/relation/calculations.rb -ActiveRecord::Calculations.class_exec do - private - - def perform_calculation(operation, column_name, options = {}) - operation = operation.to_s.downcase - - # If #count is used with #distinct / #uniq it is considered distinct. - # (eg. relation.distinct.count) - distinct = self.distinct_value - - if operation == "count" - column_name ||= select_for_count - - outer_join = !arel.ast.grep(Arel::Nodes::OuterJoin).empty? rescue true - distinct = true if outer_join - - column_name = primary_key if column_name == :all && distinct - distinct = nil if column_name =~ /\s*DISTINCT[\s(]+/i - end - - if group_values.any? - execute_grouped_calculation(operation, column_name, distinct) - else - execute_simple_calculation(operation, column_name, distinct) - end - end -end diff --git a/lib/active_record/table_association_name_patch.rb b/lib/active_record/table_association_name_patch.rb new file mode 100644 index 00000000..cbe61c23 --- /dev/null +++ b/lib/active_record/table_association_name_patch.rb @@ -0,0 +1,23 @@ +# https://github.com/rails/rails/issues/32374#issuecomment-378122738 +module ActiveRecord + class TableMetadata + + def associated_table(table_name) + association = klass._reflect_on_association(table_name) || klass._reflect_on_association(table_name.to_s.singularize) + + if !association && table_name == arel_table.name + return self + elsif association && !association.polymorphic? + association_klass = association.klass + arel_table = association_klass.arel_table + else + type_caster = TypeCaster::Connection.new(klass, table_name) + association_klass = nil + arel_table = Arel::Table.new(table_name, type_caster: type_caster) + end + + TableMetadata.new(association_klass, arel_table, association) + end + + end +end From 52b171e20b5299d7341b593db0f81fb224de7053 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 24 May 2019 12:24:21 -0500 Subject: [PATCH 06/50] Lots of de-squeeling --- app/models/publication.rb | 62 ++++++----- app/models/vocab_term.rb | 6 +- app/routines/exercises/import/quadbase.rb | 6 +- app/routines/search_exercises.rb | 100 +++++++++--------- app/routines/search_vocab_terms.rb | 96 +++++++++-------- lib/publishable/active_record.rb | 67 +++++++----- lib/tasks/vocab_terms/unlink.rake | 2 +- .../application_access_policy_spec.rb | 2 +- .../api/v1/attachments_controller_spec.rb | 4 +- .../api/v1/exercises_controller_spec.rb | 25 +++-- spec/routines/search_exercises_spec.rb | 23 ++-- spec/routines/search_vocab_terms_spec.rb | 6 +- 12 files changed, 224 insertions(+), 175 deletions(-) diff --git a/app/models/publication.rb b/app/models/publication.rb index 26eb3d9f..90166318 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -39,20 +39,23 @@ class Publication < ActiveRecord::Base scope :with_id, ->(id) do nn, vv = id.to_s.split('@') - joins(:publication_group).where do - wheres = (publication_group.uuid == nn) | (publication_group.number == nn) + pub = Publication.arel_table + pubg = PublicationGroup.arel_table - case vv + wheres = pubg[:uuid].eq(nn).or(pubg[:number].eq(nn)) + case vv when NilClass - (wheres | (uuid == nn)) & (published_at != nil) + wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) when 'draft', 'd' - wheres & (published_at == nil) + wheres.and(pub[:published_at].not_eq(nil)) when 'latest' wheres else - wheres & (version == vv) - end - end.order {[publication_group.number.asc, version.desc]} + wheres.and(pub[:version].eq(vv)) + end + + joins(publication: :publication_group).where(wheres + ).order( [pubg[:number].asc, pub[:version].desc] ) end scope :visible_for, ->(options) do @@ -64,22 +67,33 @@ class Publication < ActiveRecord::Base next all if user.administrator user_id = user.id - joins do - [ - authors, - copyright_holders, - publication_group.list_publication_groups.outer.list.outer.list_owners, - publication_group.list_publication_groups.outer.list.outer.list_editors, - publication_group.list_publication_groups.outer.list.outer.list_readers - ].map(&:outer) - end.where do - (published_at != nil ) | - (authors.user_id == user_id ) | - (copyright_holders.user_id == user_id ) | - ((list_owners.owner_id == user_id) & (list_owners.owner_type == 'User')) | - ((list_editors.editor_id == user_id) & (list_editors.editor_type == 'User')) | - ((list_readers.reader_id == user_id) & (list_readers.reader_type == 'User')) - end + pub = Publication.arel_table + au = Author.arel_table + cw = CopyrightHolder.arel_table + pubg = PublicationGroup.arel_table + lpg = ListPublicationGroup.arel_table + l_own = ListOwner.arel_table + l_edit = ListEditor.arel_table + l_read = ListReader.arel_table + + me = self.arel_table + + joins(me.join(pub).on(pub[:publishable_id].eq(me[:id]), pub[:publishable_type].eq(self.name)) + .join(au).on(au[:publication_id].eq(pub[:id])) + .join(cw).on(cw[:publication_id].eq(pub[:id])) + .join(pubg).on(pub[:publication_group_id].eq(pubg[:id])) + .outer_join(lpg).on(lpg[:publication_group_id].eq(pubg[:id])) + .outer_join(l_own).on(l_own[:list_id].eq(lpg[:id])) + .outer_join(l_edit).on(l_edit[:list_id].eq(lpg[:id])) + .outer_join(l_read).on(l_read[:list_id].eq(lpg[:id])).join_sources + ).where( + pub[:published_at].not_eq(nil) + .or(au[:user_id].eq(user_id)) + .or(cw[:user_id].eq(user_id)) + .or(l_own[:owner_id].eq(user_id).and(l_own[:owner_type].eq('User'))) + .or(l_edit[:editor_id].eq(user_id).and(l_edit[:editor_type].eq('User'))) + .or(l_read[:reader_id].eq(user_id).and(l_read[:reader_type].eq('User')))) + end # By default, returns both the latest published version and the latest draft, if any diff --git a/app/models/vocab_term.rb b/app/models/vocab_term.rb index 3f99ec71..fad2336f 100644 --- a/app/models/vocab_term.rb +++ b/app/models/vocab_term.rb @@ -122,12 +122,10 @@ def before_publication end def after_publication - vt = VocabTerm.arel_table - pub = Publication.arel_table last_def = VocabTerm.joins(publication: :publication_group) .where(publication: {publication_group: {number: number}}) - .where (vt[:id] != id) - .order (vt[:publication] { pub[:version].desc}) + .where.not(id: id) + .order(Publication.arel_table[:version].desc) .limit(1) .pluck(:definition) return if definition == last_def diff --git a/app/routines/exercises/import/quadbase.rb b/app/routines/exercises/import/quadbase.rb index a9e543f3..89952e72 100644 --- a/app/routines/exercises/import/quadbase.rb +++ b/app/routines/exercises/import/quadbase.rb @@ -36,10 +36,12 @@ def import_question(hash) end id_tag = "exid:qb:#{hash['id']}" + pub = Publication.arel_table + pubg = PublicationGroup.arel_table latest_exercise = Exercise .joins([{publication: :publication_group}, {exercise_tags: :tag}]) - .where(exercise_tags: {tag: {name: id_tag}}) - .order {[publication.publication_group.number.desc, publication.version.desc]}.first + .where(exercise_tags: {tag: {name: id_tag}} + ).order(pubg[:number].desc, pub[:version].desc).first publication = import_metadata(exercise.publication, hash['attribution']) diff --git a/app/routines/search_exercises.rb b/app/routines/search_exercises.rb index d7d43097..4fd62d96 100644 --- a/app/routines/search_exercises.rb +++ b/app/routines/search_exercises.rb @@ -36,6 +36,9 @@ def exec(params = {}, options = {}) with.default_keyword :content ex = Exercise.arel_table + qu = Question.arel_table + st = Stem.arel_table + ans = Answer.arel_table with.keyword :id do |ids| ids.each do |id| @@ -64,24 +67,25 @@ def exec(params = {}, options = {}) @items = @items.where(publication_groups: { number: sanitized_numbers }) else # Combine the id's one at a time using Squeel - @items = @items.where do - only_numbers = sanitized_uids.select { |suid| suid.second.blank? }.map(&:first) - only_versions = sanitized_uids.select { |suid| suid.first.blank? }.map(&:second) - full_uids = sanitized_uids.reject { |suid| suid.first.blank? || suid.second.blank? } - - cumulative_query = publication.publication_group.number.in(only_numbers) | - publication.version.in(only_versions) - - full_uids.each do |full_uid| - sanitized_number = full_uid.first - sanitized_version = full_uid.second - query = (publication.publication_group.number == sanitized_number) & - (publication.version == sanitized_version) - cumulative_query = cumulative_query | query + pub = Publication.arel_table + pubg = PublicationGroup.arel_table + + only_numbers = sanitized_uids.select { |suid| suid.second.blank? }.map(&:first) + only_versions = sanitized_uids.select { |suid| suid.first.blank? }.map(&:second) + full_uids = sanitized_uids.reject { |suid| suid.first.blank? || suid.second.blank? } + + cumulative_query = pubg[:number].in(only_numbers).or( + pub[:version].in(only_versions)) + + full_uids.each do |full_uid| + sanitized_number = full_uid.first + sanitized_version = full_uid.second + query = pubg[:number].eq(sanitized_number).and( + pub[:version].eq(sanitized_version)) + cumulative_query = cumulative_query.or(query) end - cumulative_query - end + @items = @items.where(cumulative_query) end end end @@ -161,14 +165,12 @@ def exec(params = {}, options = {}) prepend_wildcard: true) next @items = @items.none if sanitized_contents.empty? - @items = @items.joins {[questions.outer.stems.outer, questions.outer.answers.outer]} - .where do - title.like_any(sanitized_contents) | - stimulus.like_any(sanitized_contents) | - questions.stimulus.like_any(sanitized_contents) | - questions.stems.content.like_any(sanitized_contents) | - questions.answers.content.like_any(sanitized_contents) - end + @items = @items.left_joins(questions: [:stems, :answers]).where( + ex[:title].matches_any(sanitized_contents) + .or(ex[:stimulus].matches_any(sanitized_contents)) + .or(qu[:stimulus].matches_any(sanitized_contents)) + .or(st[:content].matches_any(sanitized_contents)) + .or(ans[:content].matches_any(sanitized_contents))) end end @@ -177,12 +179,12 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - @items = @items.joins(publication: { authors: { user: :account } }).where do - openstax_accounts_accounts.username.like_any(sn) | - openstax_accounts_accounts.first_name.like_any(sn) | - openstax_accounts_accounts.last_name.like_any(sn) | - openstax_accounts_accounts.full_name.like_any(sn) - end + acct = OpenStax::Accounts::Account.arel_table + @items = @items.joins(publication: { authors: { user: :account } }).where( + acct[:username].matches_any(sn) + .or(acct[:first_name].matches_any(sn)) + .or(acct[:last_name].matches_any(sn)) + .or(acct[:full_name].matches_any(sn))) end end @@ -191,12 +193,12 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - @items = @items.joins(publication: { copyright_holders: { user: :account } }).where do - openstax_accounts_accounts.username.like_any(sn) | - openstax_accounts_accounts.first_name.like_any(sn) | - openstax_accounts_accounts.last_name.like_any(sn) | - openstax_accounts_accounts.full_name.like_any(sn) - end + acct = OpenStax::Accounts::Account.arel_table + @items = @items.joins(publication: { copyright_holders: { user: :account } }).where( + acct[:username].matches_any(sn) + .or(acct[:first_name].matches_any(sn)) + .or(acct[:last_name].matches_any(sn)) + .or(acct[:full_name].matches_any(sn))) end end @@ -205,18 +207,18 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - @items = @items.joins {publication.authors.outer.user.outer.account.outer} - .joins {publication.copyright_holders.outer.user.outer.account.outer} - .where do - publication.authors.user.account.username.like_any(sn) | - publication.authors.user.account.first_name.like_any(sn) | - publication.authors.user.account.last_name.like_any(sn) | - publication.authors.user.account.full_name.like_any(sn) | - publication.copyright_holders.user.account.username.like_any(sn) | - publication.copyright_holders.user.account.first_name.like_any(sn) | - publication.copyright_holders.user.account.last_name.like_any(sn) | - publication.copyright_holders.user.account.full_name.like_any(sn) - end + acct_author = OpenStax::Accounts::Account.arel_table + acct_copyright = OpenStax::Accounts::Account.arel_table.alias('accounts_users') + @items = @items.joins(publication: { authors: { user: :account } }) + .joins(publication: { copyright_holders: { user: :account } }).where( + acct_author[:username].matches_any(sn) + .or(acct_author[:first_name].matches_any(sn)) + .or(acct_author[:last_name].matches_any(sn)) + .or(acct_author[:full_name].matches_any(sn)) + .or(acct_copyright[:username].matches_any(sn)) + .or(acct_copyright[:first_name].matches_any(sn)) + .or(acct_copyright[:last_name].matches_any(sn)) + .or(acct_copyright[:full_name].matches_any(sn))) end end end @@ -237,6 +239,6 @@ def exec(params = {}, options = {}) return unless latest_visible outputs.items = outputs.items.chainable_latest - outputs.total_count = outputs.items.limit(nil).offset(nil).reorder(nil).count + outputs.total_count = outputs.items.limit(nil).offset(nil).reorder(nil).count(:all) end end diff --git a/app/routines/search_vocab_terms.rb b/app/routines/search_vocab_terms.rb index 5ca85a56..2998e97e 100644 --- a/app/routines/search_vocab_terms.rb +++ b/app/routines/search_vocab_terms.rb @@ -35,12 +35,14 @@ def exec(params = {}, options = {}) run(:search, relation: relation, sortable_fields: SORTABLE_FIELDS, params: params) do |with| # Block to be used for searches by name or term + name_search_block = lambda do |names| + vt = VocabTerm.arel_table names.each do |nm| sanitized_names = to_string_array(nm, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_names.empty? - @items = @items.where ( name.like_any sanitized_names ) + @items = @items.where ( vt[:name].matches_any(sanitized_names )) end end @@ -73,24 +75,25 @@ def exec(params = {}, options = {}) @items = @items.where(publication_groups: { number: sanitized_numbers }) else # Combine the id's one at a time using Squeel - @items = @items.where do - only_numbers = sanitized_uids.select { |suid| suid.second.blank? }.map(&:first) - only_versions = sanitized_uids.select { |suid| suid.first.blank? }.map(&:second) - full_uids = sanitized_uids.reject { |suid| suid.first.blank? || suid.second.blank? } - - cumulative_query = publication.publication_group.number.in(only_numbers) | - publication.version.in(only_versions) - - full_uids.each do |full_uid| - sanitized_number = full_uid.first - sanitized_version = full_uid.second - query = (publication.publication_group.number == sanitized_number) & - (publication.version == sanitized_version) - cumulative_query = cumulative_query | query + pub = Publication.arel_table + pubg = PublicationGroup.arel_table + + only_numbers = sanitized_uids.select { |suid| suid.second.blank? }.map(&:first) + only_versions = sanitized_uids.select { |suid| suid.first.blank? }.map(&:second) + full_uids = sanitized_uids.reject { |suid| suid.first.blank? || suid.second.blank? } + + cumulative_query = pubg[:number].in(only_numbers).or( + pub[:version].in(only_versions)) + + full_uids.each do |full_uid| + sanitized_number = full_uid.first + sanitized_version = full_uid.second + query = pubg[:number].eq(sanitized_number).and( + pub[:version].eq(sanitized_version)) + cumulative_query = cumulative_query.or(query) end - cumulative_query - end + @items = @items.where(cumulative_query) end end end @@ -160,23 +163,24 @@ def exec(params = {}, options = {}) with.keyword :term, &name_search_block with.keyword :definition do |definitions| + vt = VocabTerm.arel_table definitions.each do |df| sanitized_definitions = to_string_array(df, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_definitions.empty? - @items = @items.where( definition.like_any sanitized_definitions ) + @items = @items.where( vt[:definition].matches_any(sanitized_definitions) ) end end with.keyword :content do |contents| + vt = VocabTerm.arel_table contents.each do |content| sanitized_contents = to_string_array(content, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_contents.empty? - @items = @items.where do - name.like_any(sanitized_contents) | definition.like_any(sanitized_contents) - end + @items = @items.where(vt[:name].matches_any(sanitized_contents).or( + vt[:definition].matches_any(sanitized_contents))) end end @@ -185,12 +189,12 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - @items = @items.joins(publication: { authors: { user: :account } }).where do - openstax_accounts_accounts.username.like_any(sn) | - openstax_accounts_accounts.first_name.like_any(sn) | - openstax_accounts_accounts.last_name.like_any(sn) | - openstax_accounts_accounts.full_name.like_any(sn) - end + acct = OpenStax::Accounts::Account.arel_table + @items = @items.joins(publication: { authors: { user: :account } }).where( + acct[:username].matches_any(sn) + .or(acct[:first_name].matches_any(sn)) + .or(acct[:last_name].matches_any(sn)) + .or(acct[:full_name].matches_any(sn))) end end @@ -199,12 +203,12 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - @items = @items.joins(publication: { copyright_holders: { user: :account } }).where do - openstax_accounts_accounts.username.like_any(sn) | - openstax_accounts_accounts.first_name.like_any(sn) | - openstax_accounts_accounts.last_name.like_any(sn) | - openstax_accounts_accounts.full_name.like_any(sn) - end + acct = OpenStax::Accounts::Account.arel_table + @items = @items.joins(publication: { copyright_holders: { user: :account } }).where( + acct[:username].matches_any(sn) + .or(acct[:first_name].matches_any(sn)) + .or(acct[:last_name].matches_any(sn)) + .or(acct[:full_name].matches_any(sn))) end end @@ -213,18 +217,18 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - @items = @items.joins {publication.authors.outer.user.outer.account.outer} - .joins {publication.copyright_holders.outer.user.outer.account.outer} - .where do - publication.authors.user.account.username.like_any(sn) | - publication.authors.user.account.first_name.like_any(sn) | - publication.authors.user.account.last_name.like_any(sn) | - publication.authors.user.account.full_name.like_any(sn) | - publication.copyright_holders.user.account.username.like_any(sn) | - publication.copyright_holders.user.account.first_name.like_any(sn) | - publication.copyright_holders.user.account.last_name.like_any(sn) | - publication.copyright_holders.user.account.full_name.like_any(sn) - end + acct_author = OpenStax::Accounts::Account.arel_table + acct_copyright = OpenStax::Accounts::Account.arel_table.alias('accounts_users') + @items = @items.joins(publication: { authors: { user: :account } }) + .joins(publication: { copyright_holders: { user: :account } }).where( + acct_author[:username].matches_any(sn) + .or(acct_author[:first_name].matches_any(sn)) + .or(acct_author[:last_name].matches_any(sn)) + .or(acct_author[:full_name].matches_any(sn)) + .or(acct_copyright[:username].matches_any(sn)) + .or(acct_copyright[:first_name].matches_any(sn)) + .or(acct_copyright[:last_name].matches_any(sn)) + .or(acct_copyright[:full_name].matches_any(sn))) end end end @@ -245,6 +249,6 @@ def exec(params = {}, options = {}) return unless latest_visible outputs.items = outputs.items.chainable_latest - outputs.total_count = outputs.items.limit(nil).offset(nil).reorder(nil).count + outputs.total_count = outputs.items.limit(nil).offset(nil).reorder(nil).count(:all) end end diff --git a/lib/publishable/active_record.rb b/lib/publishable/active_record.rb index 5a400ee6..94eb154a 100644 --- a/lib/publishable/active_record.rb +++ b/lib/publishable/active_record.rb @@ -20,29 +20,31 @@ def publishable(options = {}) to: :publication scope :published, -> do - joins(:publication).where.not(publications: { published_at: nil }) + joins(:publication).where.not(publication: { published_at: nil }) end - scope :unpublished, -> { joins(:publication).where(publications: { published_at: nil }) } + scope :unpublished, -> { joins(:publication).where(publication: { published_at: nil }) } scope :with_id, ->(id) do nn, vv = id.to_s.split('@') - joins(publication: :publication_group).where do - wheres = (publication.publication_group.uuid == nn) | - (publication.publication_group.number == nn) + pub = Publication.arel_table + pubg = PublicationGroup.arel_table - case vv + wheres = pubg[:uuid].eq(nn).or(pubg[:number].eq(nn)) + case vv when NilClass - (wheres | (publication.uuid == nn)) & (publication.published_at != nil) + wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) when 'draft', 'd' - wheres & (publication.published_at == nil) + wheres.and(pub[:published_at].not_eq(nil)) when 'latest' wheres else - wheres & (publication.version == vv) - end - end.order { [publication.publication_group.number.asc, publication.version.desc] } + wheres.and(pub[:version].eq(vv)) + end + + joins(publication: :publication_group).where(wheres + ).order( [pubg[:number].asc, pub[:version].desc] ) end scope :visible_for, ->(options) do @@ -54,22 +56,33 @@ def publishable(options = {}) next all if user.administrator user_id = user.id - joins do - [ - publication.authors, - publication.copyright_holders, - publication.publication_group.list_publication_groups.outer.list.outer.list_owners, - publication.publication_group.list_publication_groups.outer.list.outer.list_editors, - publication.publication_group.list_publication_groups.outer.list.outer.list_readers - ].map(&:outer) - end.where do - (publication.published_at != nil ) | - (authors.user_id == user_id ) | - (copyright_holders.user_id == user_id ) | - ((list_owners.owner_id == user_id) & (list_owners.owner_type == 'User')) | - ((list_editors.editor_id == user_id) & (list_editors.editor_type == 'User')) | - ((list_readers.reader_id == user_id) & (list_readers.reader_type == 'User')) - end + pub = Publication.arel_table + au = Author.arel_table + cw = CopyrightHolder.arel_table + pubg = PublicationGroup.arel_table + lpg = ListPublicationGroup.arel_table + l_own = ListOwner.arel_table + l_edit = ListEditor.arel_table + l_read = ListReader.arel_table + + me = self.arel_table + + joins(me.join(pub).on(pub[:publishable_id].eq(me[:id]), pub[:publishable_type].eq(self.name)) + .join(au).on(au[:publication_id].eq(pub[:id])) + .join(cw).on(cw[:publication_id].eq(pub[:id])) + .join(pubg).on(pub[:publication_group_id].eq(pubg[:id])) + .outer_join(lpg).on(lpg[:publication_group_id].eq(pubg[:id])) + .outer_join(l_own).on(l_own[:list_id].eq(lpg[:id])) + .outer_join(l_edit).on(l_edit[:list_id].eq(lpg[:id])) + .outer_join(l_read).on(l_read[:list_id].eq(lpg[:id])).join_sources + ).where( + pub[:published_at].not_eq(nil) + .or(au[:user_id].eq(user_id)) + .or(cw[:user_id].eq(user_id)) + .or(l_own[:owner_id].eq(user_id).and(l_own[:owner_type].eq('User'))) + .or(l_edit[:editor_id].eq(user_id).and(l_edit[:editor_type].eq('User'))) + .or(l_read[:reader_id].eq(user_id).and(l_read[:reader_type].eq('User')))) + end # By default, returns both the latest published version and the latest draft, if any diff --git a/lib/tasks/vocab_terms/unlink.rake b/lib/tasks/vocab_terms/unlink.rake index ad787cfa..2acdef66 100644 --- a/lib/tasks/vocab_terms/unlink.rake +++ b/lib/tasks/vocab_terms/unlink.rake @@ -1,7 +1,7 @@ namespace :vocab_terms do desc 'unlinks all vocab terms that are currently linked to other terms' task unlink: :environment do - VocabTerm.joins(:vocab_distractors).latest.uniq.find_in_batches do |vocab_terms| + VocabTerm.joins(:vocab_distractors).latest.distinct.find_in_batches do |vocab_terms| VocabTerm.transaction do vocab_terms.each do |vocab_term| vocab_term = vocab_term.new_version if vocab_term.is_published? diff --git a/spec/access_policies/doorkeeper/application_access_policy_spec.rb b/spec/access_policies/doorkeeper/application_access_policy_spec.rb index 9ce63228..142bdf43 100644 --- a/spec/access_policies/doorkeeper/application_access_policy_spec.rb +++ b/spec/access_policies/doorkeeper/application_access_policy_spec.rb @@ -4,7 +4,7 @@ let(:anon) { AnonymousUser.instance } let(:user) { FactoryBot.create(:user) } let(:admin) { FactoryBot.create(:user, :administrator) } - let(:app) { FactoryBot.build(:doorkeeper_application) } + let(:app) { FactoryBot.create(:doorkeeper_application) } let(:another_app) { FactoryBot.create(:doorkeeper_application) } context 'read, update' do diff --git a/spec/controllers/api/v1/attachments_controller_spec.rb b/spec/controllers/api/v1/attachments_controller_spec.rb index ed542385..160ad863 100644 --- a/spec/controllers/api/v1/attachments_controller_spec.rb +++ b/spec/controllers/api/v1/attachments_controller_spec.rb @@ -46,7 +46,7 @@ module Api::V1 it 'attaches a file to an exercise' do expect do - api_post :create, user_token, params: { exercise_id: exercise_id, file: image } + api_post :create, user_token, params: { exercise_id: exercise_id }, file: image end.to change{ exercise.attachments.count }.by(1) expect(response).to have_http_status(:success) end @@ -54,7 +54,7 @@ module Api::V1 it 'creates a draft if needed' do exercise.publication.publish.save! expect do - api_post :create, user_token, params: { exercise_id: exercise_id, file: image } + api_post :create, user_token, params: { exercise_id: exercise_id }, file: image end.to change{ exercise.publication_group.reload.latest_version }.from(1).to(2) expect(response).to have_http_status(:success) end diff --git a/spec/controllers/api/v1/exercises_controller_spec.rb b/spec/controllers/api/v1/exercises_controller_spec.rb index ccc59965..ce4727a5 100644 --- a/spec/controllers/api/v1/exercises_controller_spec.rb +++ b/spec/controllers/api/v1/exercises_controller_spec.rb @@ -34,16 +34,21 @@ module Api::V1 10.times { FactoryBot.create(:exercise, :published) } - tested_strings = ["%adipisci%", "%draft%"] - Exercise.joins {questions.outer.stems.outer} - .joins {questions.outer.answers.outer} - .where do - title.like_any(tested_strings) |\ - stimulus.like_any(tested_strings) |\ - questions.stimulus.like_any(tested_strings) |\ - stems.content.like_any(tested_strings) |\ - answers.content.like_any(tested_strings) - end.delete_all + ex = Exercise.arel_table + qu = Question.arel_table + st = Stem.arel_table + ans = Answer.arel_table + + tested_strings = [ "%adipisci%", "%draft%" ] + + ex_ids = Exercise.left_joins(questions: [:stems, :answers]).where( + ex[:title].matches_any(tested_strings) + .or(ex[:stimulus].matches_any(tested_strings)) + .or(qu[:stimulus].matches_any(tested_strings)) + .or(st[:content].matches_any(tested_strings)) + .or(ans[:content].matches_any(tested_strings))).pluck(:id) + + Exercise.where(id: ex_ids).delete_all @exercise_1 = FactoryBot.build(:exercise, :published) Api::V1::Exercises::Representer.new(@exercise_1).from_hash( diff --git a/spec/routines/search_exercises_spec.rb b/spec/routines/search_exercises_spec.rb index 94549879..02f18273 100644 --- a/spec/routines/search_exercises_spec.rb +++ b/spec/routines/search_exercises_spec.rb @@ -6,14 +6,21 @@ 10.times { FactoryBot.create(:exercise, :published) } + ex = Exercise.arel_table + qu = Question.arel_table + st = Stem.arel_table + ans = Answer.arel_table + tested_strings = [ "%adipisci%", "%draft%" ] - Exercise.joins {questions.outer.stems.outer} - .joins {questions.outer.answers.outer} - .where {(title.like_any tested_strings) |\ - (stimulus.like_any tested_strings) |\ - (questions.stimulus.like_any tested_strings) |\ - (stems.content.like_any tested_strings) |\ - (answers.content.like_any tested_strings)}.delete_all + + ex_ids = Exercise.left_joins(questions: [:stems, :answers]).where( + ex[:title].matches_any(tested_strings) + .or(ex[:stimulus].matches_any(tested_strings)) + .or(qu[:stimulus].matches_any(tested_strings)) + .or(st[:content].matches_any(tested_strings)) + .or(ans[:content].matches_any(tested_strings))).pluck(:id) + + Exercise.where(id: ex_ids).delete_all @exercise_1 = Exercise.new Api::V1::Exercises::Representer.new(@exercise_1).from_hash( @@ -91,6 +98,8 @@ it "returns drafts that the user is allowed to see" do user = FactoryBot.create :user @exercise_draft.publication.authors << Author.new(user: user) + @exercise_draft.publication.save! + @exercise_draft.publication.publish.save! @exercise_draft.reload result = described_class.call({q: 'content:draft'}, user: user.reload) expect(result.errors).to be_empty diff --git a/spec/routines/search_vocab_terms_spec.rb b/spec/routines/search_vocab_terms_spec.rb index 07242a94..842bd3f3 100644 --- a/spec/routines/search_vocab_terms_spec.rb +++ b/spec/routines/search_vocab_terms_spec.rb @@ -7,8 +7,10 @@ 10.times { FactoryBot.create(:vocab_term, :published) } tested_strings = ["%lorem ipsu%", "%uia dolor sit ame%", "%adipiscing elit%", "draft"] - VocabTerm.where {(name.like_any tested_strings) | - (definition.like_any tested_strings)}.delete_all + + vt = VocabTerm.arel_table + VocabTerm.where(vt[:name].matches_any(tested_strings).or( + vt[:definition].matches_any(tested_strings))).delete_all @vocab_term_1 = FactoryBot.build(:vocab_term, :published) Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter.new(@vocab_term_1).from_hash( From 77b9c15c2c7fcb71698777c5d2aeb4d3e37a4b2f Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 30 May 2019 09:40:21 -0500 Subject: [PATCH 07/50] inhert from ApplicationRecord --- app/models/administrator.rb | 2 +- app/models/answer.rb | 2 +- app/models/application_record.rb | 3 +++ app/models/attachment.rb | 2 +- app/models/author.rb | 2 +- app/models/class_license.rb | 2 +- app/models/collaborator_solution.rb | 2 +- app/models/combo_choice.rb | 2 +- app/models/combo_choice_answer.rb | 2 +- app/models/community_solution.rb | 2 +- app/models/copyright_holder.rb | 2 +- app/models/deputization.rb | 2 +- app/models/derivation.rb | 2 +- app/models/exercise.rb | 2 +- app/models/exercise_tag.rb | 2 +- app/models/hint.rb | 2 +- app/models/license.rb | 2 +- app/models/license_compatibility.rb | 2 +- app/models/list.rb | 2 +- app/models/list_editor.rb | 2 +- app/models/list_nesting.rb | 2 +- app/models/list_owner.rb | 2 +- app/models/list_publication_group.rb | 2 +- app/models/list_reader.rb | 2 +- app/models/logic.rb | 2 +- app/models/logic_variable.rb | 2 +- app/models/logic_variable_value.rb | 2 +- app/models/publication.rb | 2 +- app/models/publication_group.rb | 2 +- app/models/question.rb | 2 +- app/models/question_dependency.rb | 2 +- app/models/stem.rb | 2 +- app/models/stem_answer.rb | 2 +- app/models/styling.rb | 2 +- app/models/tag.rb | 2 +- app/models/trusted_application.rb | 2 +- app/models/user.rb | 2 +- app/models/vocab_distractor.rb | 2 +- app/models/vocab_term.rb | 2 +- app/models/vocab_term_tag.rb | 2 +- 40 files changed, 42 insertions(+), 39 deletions(-) create mode 100644 app/models/application_record.rb diff --git a/app/models/administrator.rb b/app/models/administrator.rb index 4af109bd..85cc0f73 100644 --- a/app/models/administrator.rb +++ b/app/models/administrator.rb @@ -1,4 +1,4 @@ -class Administrator < ActiveRecord::Base +class Administrator < ApplicationRecord belongs_to :user diff --git a/app/models/answer.rb b/app/models/answer.rb index a4e2ae17..a16e850e 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -1,4 +1,4 @@ -class Answer < ActiveRecord::Base +class Answer < ApplicationRecord attr_accessor :temp_id diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 00000000..10a4cba8 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 6b3e77ee..74ac5b8e 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -1,4 +1,4 @@ -class Attachment < ActiveRecord::Base +class Attachment < ApplicationRecord mount_uploader :asset, AssetUploader diff --git a/app/models/author.rb b/app/models/author.rb index 7b503c53..07340599 100644 --- a/app/models/author.rb +++ b/app/models/author.rb @@ -1,4 +1,4 @@ -class Author < ActiveRecord::Base +class Author < ApplicationRecord sortable_belongs_to :publication, inverse_of: :authors diff --git a/app/models/class_license.rb b/app/models/class_license.rb index eeb6a364..67a3ca3d 100644 --- a/app/models/class_license.rb +++ b/app/models/class_license.rb @@ -1,4 +1,4 @@ -class ClassLicense < ActiveRecord::Base +class ClassLicense < ApplicationRecord sortable_class scope: :class_name diff --git a/app/models/collaborator_solution.rb b/app/models/collaborator_solution.rb index 18d733a3..16086c7d 100644 --- a/app/models/collaborator_solution.rb +++ b/app/models/collaborator_solution.rb @@ -1,3 +1,3 @@ -class CollaboratorSolution < ActiveRecord::Base +class CollaboratorSolution < ApplicationRecord solution end diff --git a/app/models/combo_choice.rb b/app/models/combo_choice.rb index 417cc357..8553b456 100644 --- a/app/models/combo_choice.rb +++ b/app/models/combo_choice.rb @@ -1,4 +1,4 @@ -class ComboChoice < ActiveRecord::Base +class ComboChoice < ApplicationRecord belongs_to :stem diff --git a/app/models/combo_choice_answer.rb b/app/models/combo_choice_answer.rb index 5768674a..cb0d1f1d 100644 --- a/app/models/combo_choice_answer.rb +++ b/app/models/combo_choice_answer.rb @@ -1,4 +1,4 @@ -class ComboChoiceAnswer < ActiveRecord::Base +class ComboChoiceAnswer < ApplicationRecord belongs_to :combo_choice belongs_to :answer diff --git a/app/models/community_solution.rb b/app/models/community_solution.rb index b18278bb..fd57a8ce 100644 --- a/app/models/community_solution.rb +++ b/app/models/community_solution.rb @@ -1,4 +1,4 @@ -class CommunitySolution < ActiveRecord::Base +class CommunitySolution < ApplicationRecord publishable solution end diff --git a/app/models/copyright_holder.rb b/app/models/copyright_holder.rb index e0ec514a..fe99e368 100644 --- a/app/models/copyright_holder.rb +++ b/app/models/copyright_holder.rb @@ -1,4 +1,4 @@ -class CopyrightHolder < ActiveRecord::Base +class CopyrightHolder < ApplicationRecord sortable_belongs_to :publication, inverse_of: :copyright_holders diff --git a/app/models/deputization.rb b/app/models/deputization.rb index 3ba86426..1d444f33 100644 --- a/app/models/deputization.rb +++ b/app/models/deputization.rb @@ -1,4 +1,4 @@ -class Deputization < ActiveRecord::Base +class Deputization < ApplicationRecord belongs_to :deputizer, class_name: 'User', inverse_of: :child_deputizations belongs_to :deputy, polymorphic: true diff --git a/app/models/derivation.rb b/app/models/derivation.rb index dded3686..fb2b2241 100644 --- a/app/models/derivation.rb +++ b/app/models/derivation.rb @@ -1,4 +1,4 @@ -class Derivation < ActiveRecord::Base +class Derivation < ApplicationRecord sortable_belongs_to :derived_publication, class_name: 'Publication', inverse_of: :sources belongs_to :source_publication, class_name: 'Publication', inverse_of: :derivations diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 7256b588..82b038f3 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -1,4 +1,4 @@ -class Exercise < ActiveRecord::Base +class Exercise < ApplicationRecord EQUALITY_ASSOCIATIONS = [ :attachments, diff --git a/app/models/exercise_tag.rb b/app/models/exercise_tag.rb index 0c6a9c7b..095b985e 100644 --- a/app/models/exercise_tag.rb +++ b/app/models/exercise_tag.rb @@ -1,4 +1,4 @@ -class ExerciseTag < ActiveRecord::Base +class ExerciseTag < ApplicationRecord belongs_to :exercise belongs_to :tag diff --git a/app/models/hint.rb b/app/models/hint.rb index 66d87a1f..662e5fa8 100644 --- a/app/models/hint.rb +++ b/app/models/hint.rb @@ -1,4 +1,4 @@ -class Hint < ActiveRecord::Base +class Hint < ApplicationRecord sortable_belongs_to :question, inverse_of: :hints diff --git a/app/models/license.rb b/app/models/license.rb index 46ee31df..1f1667a2 100644 --- a/app/models/license.rb +++ b/app/models/license.rb @@ -1,4 +1,4 @@ -class License < ActiveRecord::Base +class License < ApplicationRecord has_many :publications, dependent: :destroy has_many :class_licenses, dependent: :destroy diff --git a/app/models/license_compatibility.rb b/app/models/license_compatibility.rb index 3c3cc7b7..7dd98620 100644 --- a/app/models/license_compatibility.rb +++ b/app/models/license_compatibility.rb @@ -1,4 +1,4 @@ -class LicenseCompatibility < ActiveRecord::Base +class LicenseCompatibility < ApplicationRecord belongs_to :original_license, class_name: 'License', inverse_of: :combined_license_compatibilities diff --git a/app/models/list.rb b/app/models/list.rb index c776dc46..1b552e1c 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -1,4 +1,4 @@ -class List < ActiveRecord::Base +class List < ApplicationRecord publishable diff --git a/app/models/list_editor.rb b/app/models/list_editor.rb index 8312e4a9..279f1933 100644 --- a/app/models/list_editor.rb +++ b/app/models/list_editor.rb @@ -1,4 +1,4 @@ -class ListEditor < ActiveRecord::Base +class ListEditor < ApplicationRecord belongs_to :list, inverse_of: :list_editors belongs_to :editor, polymorphic: true diff --git a/app/models/list_nesting.rb b/app/models/list_nesting.rb index 781cdcf3..240d12a4 100644 --- a/app/models/list_nesting.rb +++ b/app/models/list_nesting.rb @@ -1,4 +1,4 @@ -class ListNesting < ActiveRecord::Base +class ListNesting < ApplicationRecord belongs_to :parent_list, class_name: 'List', inverse_of: :child_list_nestings belongs_to :child_list, class_name: 'List', inverse_of: :parent_list_nesting diff --git a/app/models/list_owner.rb b/app/models/list_owner.rb index c3f75480..85ee0657 100644 --- a/app/models/list_owner.rb +++ b/app/models/list_owner.rb @@ -1,4 +1,4 @@ -class ListOwner < ActiveRecord::Base +class ListOwner < ApplicationRecord belongs_to :list, inverse_of: :list_owners belongs_to :owner, polymorphic: true diff --git a/app/models/list_publication_group.rb b/app/models/list_publication_group.rb index e47c6be5..c8d418f7 100644 --- a/app/models/list_publication_group.rb +++ b/app/models/list_publication_group.rb @@ -1,4 +1,4 @@ -class ListPublicationGroup < ActiveRecord::Base +class ListPublicationGroup < ApplicationRecord sortable_belongs_to :list, inverse_of: :list_publication_groups belongs_to :publication_group, inverse_of: :list_publication_groups diff --git a/app/models/list_reader.rb b/app/models/list_reader.rb index cc7e7e7a..283fc1e7 100644 --- a/app/models/list_reader.rb +++ b/app/models/list_reader.rb @@ -1,4 +1,4 @@ -class ListReader < ActiveRecord::Base +class ListReader < ApplicationRecord belongs_to :list, inverse_of: :list_readers belongs_to :reader, polymorphic: true diff --git a/app/models/logic.rb b/app/models/logic.rb index d6386608..ca62cc7b 100644 --- a/app/models/logic.rb +++ b/app/models/logic.rb @@ -1,4 +1,4 @@ -class Logic < ActiveRecord::Base +class Logic < ApplicationRecord belongs_to :parent, polymorphic: true, inverse_of: :logic diff --git a/app/models/logic_variable.rb b/app/models/logic_variable.rb index e93a32aa..a219dc58 100644 --- a/app/models/logic_variable.rb +++ b/app/models/logic_variable.rb @@ -1,4 +1,4 @@ -class LogicVariable < ActiveRecord::Base +class LogicVariable < ApplicationRecord VARIABLE_REGEX = /\A[_a-zA-Z]{1}\w*\z/ diff --git a/app/models/logic_variable_value.rb b/app/models/logic_variable_value.rb index 0ca85403..88b56716 100644 --- a/app/models/logic_variable_value.rb +++ b/app/models/logic_variable_value.rb @@ -1,4 +1,4 @@ -class LogicVariableValue < ActiveRecord::Base +class LogicVariableValue < ApplicationRecord belongs_to :logic_variable diff --git a/app/models/publication.rb b/app/models/publication.rb index 90166318..fb3492d1 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -1,4 +1,4 @@ -class Publication < ActiveRecord::Base +class Publication < ApplicationRecord belongs_to :publication_group, inverse_of: :publications belongs_to :publishable, polymorphic: true, inverse_of: :publication, touch: true diff --git a/app/models/publication_group.rb b/app/models/publication_group.rb index e3eb0149..2d21b792 100644 --- a/app/models/publication_group.rb +++ b/app/models/publication_group.rb @@ -1,4 +1,4 @@ -class PublicationGroup < ActiveRecord::Base +class PublicationGroup < ApplicationRecord has_many :publications, dependent: :destroy, inverse_of: :publication_group, autosave: true diff --git a/app/models/question.rb b/app/models/question.rb index 3580a73f..52b9164d 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -1,4 +1,4 @@ -class Question < ActiveRecord::Base +class Question < ApplicationRecord attr_accessor :temp_id diff --git a/app/models/question_dependency.rb b/app/models/question_dependency.rb index 732698a1..4fc260b9 100644 --- a/app/models/question_dependency.rb +++ b/app/models/question_dependency.rb @@ -1,4 +1,4 @@ -class QuestionDependency < ActiveRecord::Base +class QuestionDependency < ApplicationRecord belongs_to :parent_question, class_name: 'Question', inverse_of: :child_dependencies diff --git a/app/models/stem.rb b/app/models/stem.rb index b9ae8905..227784e6 100644 --- a/app/models/stem.rb +++ b/app/models/stem.rb @@ -1,4 +1,4 @@ -class Stem < ActiveRecord::Base +class Stem < ApplicationRecord user_html :content stylable diff --git a/app/models/stem_answer.rb b/app/models/stem_answer.rb index 58c755fe..b7216bb3 100644 --- a/app/models/stem_answer.rb +++ b/app/models/stem_answer.rb @@ -1,4 +1,4 @@ -class StemAnswer < ActiveRecord::Base +class StemAnswer < ApplicationRecord belongs_to :stem belongs_to :answer diff --git a/app/models/styling.rb b/app/models/styling.rb index ff947d81..250208e2 100644 --- a/app/models/styling.rb +++ b/app/models/styling.rb @@ -1,4 +1,4 @@ -class Styling < ActiveRecord::Base +class Styling < ApplicationRecord belongs_to :stylable, polymorphic: true, inverse_of: :stylings diff --git a/app/models/tag.rb b/app/models/tag.rb index 1fdf3964..ab70975b 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -1,4 +1,4 @@ -class Tag < ActiveRecord::Base +class Tag < ApplicationRecord has_many :exercise_tags, dependent: :destroy has_many :vocab_term_tags, dependent: :destroy diff --git a/app/models/trusted_application.rb b/app/models/trusted_application.rb index 7934d137..1825aeb2 100644 --- a/app/models/trusted_application.rb +++ b/app/models/trusted_application.rb @@ -1,4 +1,4 @@ -class TrustedApplication < ActiveRecord::Base +class TrustedApplication < ApplicationRecord belongs_to :application, class_name: 'Doorkeeper::Application', inverse_of: :trusted_application diff --git a/app/models/user.rb b/app/models/user.rb index dd3d8122..8572d945 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,4 @@ -class User < ActiveRecord::Base +class User < ApplicationRecord USERNAME_FORBIDDEN_CHAR_REGEX = /[^\w-]/ diff --git a/app/models/vocab_distractor.rb b/app/models/vocab_distractor.rb index 51789ba9..4b03723c 100644 --- a/app/models/vocab_distractor.rb +++ b/app/models/vocab_distractor.rb @@ -1,4 +1,4 @@ -class VocabDistractor < ActiveRecord::Base +class VocabDistractor < ApplicationRecord belongs_to :vocab_term, inverse_of: :vocab_distractors belongs_to :distractor_publication_group, class_name: 'PublicationGroup', inverse_of: :vocab_distractors diff --git a/app/models/vocab_term.rb b/app/models/vocab_term.rb index fad2336f..b0b839ec 100644 --- a/app/models/vocab_term.rb +++ b/app/models/vocab_term.rb @@ -1,4 +1,4 @@ -class VocabTerm < ActiveRecord::Base +class VocabTerm < ApplicationRecord EQUALITY_ASSOCIATIONS = [ :tags, diff --git a/app/models/vocab_term_tag.rb b/app/models/vocab_term_tag.rb index 58f9cfab..54e959b1 100644 --- a/app/models/vocab_term_tag.rb +++ b/app/models/vocab_term_tag.rb @@ -1,4 +1,4 @@ -class VocabTermTag < ActiveRecord::Base +class VocabTermTag < ApplicationRecord belongs_to :vocab_term belongs_to :tag From 828373dff8c4be84490279774a8f9a278aefa037 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 30 May 2019 11:37:30 -0500 Subject: [PATCH 08/50] gem updates --- Gemfile | 19 ++++---- Gemfile.lock | 123 ++++++++++++++++++++++----------------------------- 2 files changed, 60 insertions(+), 82 deletions(-) diff --git a/Gemfile b/Gemfile index 6fe058c5..ec467ceb 100644 --- a/Gemfile +++ b/Gemfile @@ -62,8 +62,7 @@ gem 'whenever' gem 'omniauth-oauth2', '~> 1.3.1' # OpenStax Accounts integration -#gem 'openstax_accounts', '~> 7.12.0' -gem 'openstax_accounts', path: '../accounts-rails' +gem 'openstax_accounts' # Access control for API's @@ -71,9 +70,7 @@ gem 'doorkeeper' # API versioning and documentation gem 'representable', '~> 3.0.0' -#gem 'openstax_api', '~> 8.3.0' -#gem 'openstax_api', github: 'openstax/openstax_api', branch: 'rails5' -gem 'openstax_api', path: '../openstax_api' +gem 'openstax_api' gem 'apipie-rails' gem 'maruku' @@ -81,8 +78,7 @@ gem 'maruku' gem 'lev' # Contract management -#gem 'fine_print' -gem 'fine_print', github: 'lml/fine_print', branch: 'rails5' +gem 'fine_print' # Keyword search gem 'keyword_search' @@ -112,8 +108,7 @@ gem 'eco' gem 'deep_cloneable' # Sortable objects -#gem 'sortability' -gem 'sortability', github: 'openstax/sortability', branch: 'rails5' +gem 'sortability' # Comments on objects gem 'commontator' @@ -137,8 +132,7 @@ gem 'a15k_client', branch: 'master' # Notify developers of Exceptions in production -#gem 'openstax_rescue_from', '~> 3.0.0' -gem 'openstax_rescue_from', github: 'openstax/rescue_from', branch: 'rails5' +gem 'openstax_rescue_from' # Sentry integration (the require disables automatic Rails integration since we use rescue_from) gem 'sentry-raven', require: 'raven/base' @@ -176,6 +170,9 @@ group :development, :test do # Call 'debugger' anywhere in the code to stop execution and get a debugger console gem 'byebug' + # Some controller test support + gem 'rails-controller-testing' + # Use RSpec for tests gem 'rspec-rails' diff --git a/Gemfile.lock b/Gemfile.lock index d2f6b045..c99c6742 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,67 +8,10 @@ GIT json typhoeus (~> 1.0, >= 1.0.1) -GIT - remote: https://github.com/lml/fine_print.git - revision: 6efd8c8ae1c9800e5cc2b082bd8b467e7df36430 - branch: rails5 - specs: - fine_print (4.0.1) - action_interceptor (>= 1.0) - jquery-rails - rails (>= 4.2) - responders - -GIT - remote: https://github.com/openstax/rescue_from.git - revision: 20255f01002b452733cbb66911a7db9d065e2f10 - branch: rails5 - specs: - openstax_rescue_from (3.0.0) - rails (>= 3.1, < 6.0) - -GIT - remote: https://github.com/openstax/sortability.git - revision: 09116898fbab7b07361251891315574259db9d78 - branch: rails5 - specs: - sortability (0.1.0) - rails - -PATH - remote: ../accounts-rails - specs: - openstax_accounts (7.13.1) - action_interceptor (>= 1.0) - keyword_search (>= 1.0.0) - lev (>= 2.2.1) - oauth2 (>= 0.5.0) - omniauth (>= 1.1) - omniauth-oauth2 (>= 1.1) - openstax_api (>= 3.1.0) - openstax_utilities (>= 4.1.0) - rails (>= 4.1) - representable (>= 2.0) - -PATH - remote: ../openstax_api - specs: - openstax_api (8.3.2) - doorkeeper (>= 2.0) - exception_notification (>= 4.0) - lev (>= 1.0.0) - openstax_utilities (>= 4.2.0) - rails (>= 3.1) - representable (>= 2.4, < 4.0) - responders - roar (>= 1.0) - roar-rails (>= 1.0) - uber (< 0.1.0) - GEM remote: https://rubygems.org/ specs: - action_interceptor (1.1.0) + action_interceptor (1.1.2) rails (>= 3.1) actioncable (5.0.7.2) actionpack (= 5.0.7.2) @@ -113,7 +56,7 @@ GEM acts_as_votable (0.12.0) addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) - apipie-rails (0.5.15) + apipie-rails (0.5.16) rails (>= 4.1) arel (7.1.4) autoprefixer-rails (9.5.1.1) @@ -213,7 +156,12 @@ GEM i18n (>= 0.7) faraday (0.15.4) multipart-post (>= 1.2, < 3) - ffi (1.10.0) + ffi (1.11.1) + fine_print (5.0.0) + action_interceptor + jquery-rails + rails + responders fog-aws (3.5.0) fog-core (~> 2.1) fog-json (~> 1.1) @@ -248,7 +196,7 @@ GEM jquery-ui-rails (6.0.1) railties (>= 3.2.16) json (2.2.0) - jwt (2.1.0) + jwt (2.2.1) keyword_search (1.5.0) kgio (2.11.2) kramdown (2.1.0) @@ -262,7 +210,7 @@ GEM transaction_isolation transaction_retry libv8 (7.3.492.27.1) - lograge (0.11.0) + lograge (0.11.1) actionpack (>= 4) activesupport (>= 4) railties (>= 4) @@ -307,8 +255,34 @@ GEM omniauth-oauth2 (1.3.1) oauth2 (~> 1.0) omniauth (~> 1.2) + openstax_accounts (8.0.0) + action_interceptor + keyword_search + lev + oauth2 + omniauth + omniauth-oauth2 + openstax_api + openstax_utilities + pg + rails + representable + roar + openstax_api (9.0.0) + doorkeeper (>= 2.0) + exception_notification (>= 4.0) + lev (>= 1.0.0) + openstax_utilities (>= 4.2.0) + rails (>= 3.1) + representable (>= 2.4, < 4.0) + responders + roar (>= 1.0) + roar-rails (>= 1.0) + uber (< 0.1.0) openstax_healthcheck (0.0.3) rails (>= 3.0) + openstax_rescue_from (4.0.0) + rails (>= 3.1, < 6.0) openstax_utilities (4.2.3) keyword_search lev @@ -318,7 +292,7 @@ GEM parallel_tests (2.29.0) parallel pg (0.21.0) - public_suffix (3.0.3) + public_suffix (3.1.0) rack (2.0.7) rack-test (0.6.3) rack (>= 1.0) @@ -335,6 +309,10 @@ GEM bundler (>= 1.3.0) railties (= 5.0.7.2) sprockets-rails (>= 2.0.0) + rails-controller-testing (1.0.4) + actionpack (>= 5.0.1.x) + actionview (>= 5.0.1.x) + activesupport (>= 5.0.1.x) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) @@ -356,7 +334,7 @@ GEM rb-fsevent (0.10.3) rb-inotify (0.10.0) ffi (~> 1.0) - redis (4.1.1) + redis (4.1.2) redis-actionpack (5.0.2) actionpack (>= 4.0, < 6) redis-rack (>= 1, < 3) @@ -373,7 +351,7 @@ GEM redis-store (>= 1.2, < 2) redis-store (1.6.0) redis (>= 2.2, < 5) - remotipart (1.4.2) + remotipart (1.4.3) representable (3.0.0) declarative (~> 0.0.5) uber (~> 0.0.15) @@ -419,7 +397,7 @@ GEM rspec-support (~> 3.8.0) rspec-support (3.8.0) ruby-graphviz (1.2.4) - rubyzip (1.2.2) + rubyzip (1.2.3) sanitize (5.0.0) crass (~> 1.0.2) nokogiri (>= 1.8.0) @@ -444,6 +422,8 @@ GEM json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) + sortability (1.0.0) + rails sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) @@ -525,7 +505,7 @@ DEPENDENCIES ejs factory_bot_rails faker - fine_print! + fine_print fog-aws httparty jquery-rails @@ -542,15 +522,16 @@ DEPENDENCIES oj oj_mimic_json omniauth-oauth2 (~> 1.3.1) - openstax_accounts! - openstax_api! + openstax_accounts + openstax_api openstax_healthcheck - openstax_rescue_from! + openstax_rescue_from openstax_utilities parallel_tests pg (~> 0.18) railroady rails (~> 5.0.7.2) + rails-controller-testing rails-erd rails-html-sanitizer redis-rails @@ -566,7 +547,7 @@ DEPENDENCIES scout_apm (~> 3.0.x) sentry-raven shoulda-matchers - sortability! + sortability thin timecop turbolinks From b77ef45e4f2561a81f0af683b31e80e743fa6c90 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 30 May 2019 11:38:06 -0500 Subject: [PATCH 09/50] more deprecation fixes --- .../api/v1/exercises_controller_spec.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/spec/controllers/api/v1/exercises_controller_spec.rb b/spec/controllers/api/v1/exercises_controller_spec.rb index ce4727a5..19d9c184 100644 --- a/spec/controllers/api/v1/exercises_controller_spec.rb +++ b/spec/controllers/api/v1/exercises_controller_spec.rb @@ -104,7 +104,7 @@ module Api::V1 context "no matches" do it "does not return drafts that the user is not allowed to see" do - send method, :index, q: 'content:draft', format: :json + send method, :index, params: {q: 'content:draft'}, format: :json expect(response).to have_http_status(:success) expected_response = { @@ -119,9 +119,10 @@ module Api::V1 context "single match" do it "returns drafts that the user is allowed to see" do @exercise_draft.publication.authors << Author.new(user: @user) + @exercise_draft.publication.reload @exercise_draft.reload @user.reload - send method, :index, q: 'content:draft', format: :json + send method, :index, params: {q: 'content:draft'}, format: :json expect(response).to have_http_status(:success) expected_response = { @@ -133,7 +134,7 @@ module Api::V1 end it "returns an Exercise matching the content" do - send method, :index, q: 'content:"aDiPiScInG eLiT"', format: :json + send method, :index, params: {q: 'content:"aDiPiScInG eLiT"'}, format: :json expect(response).to have_http_status(:success) expected_response = { @@ -145,7 +146,7 @@ module Api::V1 end it "returns an Exercise matching the tags" do - send method, :index, q: 'tag:tAg1', format: :json + send method, :index, params: {q: 'tag:tAg1'}, format: :json expect(response).to have_http_status(:success) expected_response = { @@ -159,7 +160,7 @@ module Api::V1 context "multiple matches" do it "returns Exercises matching the content" do - send method, :index, q: 'content:AdIpIsCi', format: :json + send method, :index, params: {q: 'content:AdIpIsCi'}, format: :json expect(response).to have_http_status(:success) expected_response = { @@ -172,7 +173,7 @@ module Api::V1 end it "returns Exercises matching the tags" do - send method, :index, q: 'tag:TaG2', format: :json + send method, :index, params: {q: 'tag:TaG2'}, format: :json expect(response).to have_http_status(:success) expected_response = { @@ -185,7 +186,7 @@ module Api::V1 end it "sorts by multiple fields in different directions" do - send method, :index, q: 'content:aDiPiScI', order_by: "number DESC, version ASC", + send method, :index, params: {q: 'content:aDiPiScI', order_by: "number DESC, version ASC"}, format: :json expect(response).to have_http_status(:success) From f680d15d07a53bccfe0ceaf7982f27c51004695b Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 10:33:42 -0500 Subject: [PATCH 10/50] disable reaper - not compatible w/ DatabaseCleaner during tests --- config/database.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/database.yml b/config/database.yml index 9affc495..7d042d23 100644 --- a/config/database.yml +++ b/config/database.yml @@ -14,6 +14,7 @@ test: <<: *default database: '<%= ENV['OXE_TEST_DB'] || 'ox_exercises_test' %><%= \ "_#{ENV['TEST_ENV_NUMBER']}" if !ENV['TEST_ENV_NUMBER'].blank? %>' + reaping_frequency: 0 # 0 = disabled - incompatible with our DatabaseCleaner config production: <<: *default From d1e07ac8115a6c228b5dfcced3a0f9b345138dae Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 10:34:14 -0500 Subject: [PATCH 11/50] add rubocop-rails for dev --- Gemfile | 3 +++ Gemfile.lock | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Gemfile b/Gemfile index ec467ceb..a9b381f5 100644 --- a/Gemfile +++ b/Gemfile @@ -225,6 +225,9 @@ group :test do # Codecov integration gem 'codecov', require: false + # Rubocop + gem 'rubocop-rails' + end group :production do diff --git a/Gemfile.lock b/Gemfile.lock index c99c6742..05022c2d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -59,6 +59,7 @@ GEM apipie-rails (0.5.16) rails (>= 4.1) arel (7.1.4) + ast (2.4.0) autoprefixer-rails (9.5.1.1) execjs aws-ses (0.6.0) @@ -189,6 +190,7 @@ GEM i18n (1.6.0) concurrent-ruby (~> 1.0) ipaddress (0.8.3) + jaro_winkler (1.5.2) jquery-rails (4.3.3) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) @@ -291,6 +293,8 @@ GEM parallel (1.17.0) parallel_tests (2.29.0) parallel + parser (2.6.3.0) + ast (~> 2.4.0) pg (0.21.0) public_suffix (3.1.0) rack (2.0.7) @@ -329,6 +333,7 @@ GEM method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) + rainbow (3.0.0) raindrops (0.19.0) rake (12.3.2) rb-fsevent (0.10.3) @@ -396,7 +401,18 @@ GEM rspec-mocks (~> 3.8.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) + rubocop (0.71.0) + jaro_winkler (~> 1.5.1) + parallel (~> 1.10) + parser (>= 2.6) + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 1.7) + rubocop-rails (2.0.0) + rack (>= 2.0) + rubocop (>= 0.70.0) ruby-graphviz (1.2.4) + ruby-progressbar (1.10.1) rubyzip (1.2.3) sanitize (5.0.0) crass (~> 1.0.2) @@ -457,6 +473,7 @@ GEM uber (0.0.15) uglifier (4.1.20) execjs (>= 0.3.0, < 3) + unicode-display_width (1.6.0) unicorn (5.5.1) kgio (~> 2.6) raindrops (~> 0.7) @@ -542,6 +559,7 @@ DEPENDENCIES roo rspec-instafail rspec-rails + rubocop-rails sanitize sass-rails (~> 5.0) scout_apm (~> 3.0.x) From d9a7dde94022476ad61dedc6b4796511ea09e50a Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 10:39:09 -0500 Subject: [PATCH 12/50] add copyright_holder to test data --- spec/lib/publishable_spec.rb | 4 +++- spec/routines/search_exercises_spec.rb | 3 +-- spec/routines/search_vocab_terms_spec.rb | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/lib/publishable_spec.rb b/spec/lib/publishable_spec.rb index 7ff3661c..cd962d30 100644 --- a/spec/lib/publishable_spec.rb +++ b/spec/lib/publishable_spec.rb @@ -6,9 +6,11 @@ subject(:publishable) { FactoryBot.create :exercise } let(:author) { FactoryBot.create :user } + let(:coyright_holder) { FactoryBot.create :user } let(:user) { FactoryBot.create :user } - before { publishable.authors << Author.new(user: author) } + before { publishable.authors << Author.new(user: author) + publishable.copyright_holders << CopyrightHolder.new(user: author) } it 'can determine versions visible for a user' do p1 = publishable diff --git a/spec/routines/search_exercises_spec.rb b/spec/routines/search_exercises_spec.rb index 02f18273..f2d53de3 100644 --- a/spec/routines/search_exercises_spec.rb +++ b/spec/routines/search_exercises_spec.rb @@ -98,8 +98,7 @@ it "returns drafts that the user is allowed to see" do user = FactoryBot.create :user @exercise_draft.publication.authors << Author.new(user: user) - @exercise_draft.publication.save! - @exercise_draft.publication.publish.save! + @exercise_draft.publication.copyright_holders << CopyrightHolder.new(user: user) @exercise_draft.reload result = described_class.call({q: 'content:draft'}, user: user.reload) expect(result.errors).to be_empty diff --git a/spec/routines/search_vocab_terms_spec.rb b/spec/routines/search_vocab_terms_spec.rb index 842bd3f3..f1ab9d55 100644 --- a/spec/routines/search_vocab_terms_spec.rb +++ b/spec/routines/search_vocab_terms_spec.rb @@ -69,6 +69,7 @@ it "returns drafts that the user is allowed to see" do user = FactoryBot.create :user @vocab_term_draft.publication.authors << Author.new(user: user) + @vocab_term_draft.publication.copyright_holders << CopyrightHolder.new(user: user) @vocab_term_draft.reload result = described_class.call({q: 'content:draft'}, user: user) expect(result.errors).to be_empty From 1d537f4ac3f647e68223199c5344696b7eebd318 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 10:40:35 -0500 Subject: [PATCH 13/50] mostly deprecation removal - little bit more squeel removal --- .gitignore | 3 ++ .../v1/community_solutions_controller_spec.rb | 28 +++++++++---------- .../api/v1/deputizations_controller_spec.rb | 16 +++++------ .../api/v1/exercises_controller_spec.rb | 23 ++++++++------- .../api/v1/users_controller_spec.rb | 7 +++-- .../api/v1/vocab_terms_controller_spec.rb | 20 ++++++------- 6 files changed, 52 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 835ffa9f..fe656c15 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ # Ignore bundler config /.bundle +# Ignore installed gems +vendor + # Ignore the default SQLite database and yaml_db database files /db/*.sqlite3* /db/data.yml* diff --git a/spec/controllers/api/v1/community_solutions_controller_spec.rb b/spec/controllers/api/v1/community_solutions_controller_spec.rb index 7f243393..cb78dd08 100644 --- a/spec/controllers/api/v1/community_solutions_controller_spec.rb +++ b/spec/controllers/api/v1/community_solutions_controller_spec.rb @@ -11,7 +11,7 @@ module Api::V1 context "GET index" do it "assigns all solutions as @solutions" do solution = CommunitySolution.create! valid_attributes - get :index, {}, valid_session + get :index, session: valid_session expect(assigns(:solutions)).to eq([solution]) end end @@ -19,7 +19,7 @@ module Api::V1 context "GET show" do it "assigns the requested solution as @solution" do solution = CommunitySolution.create! valid_attributes - get :show, {id: solution.to_param}, valid_session + get :show, params: { id: solution.to_param }, session: valid_session expect(assigns(:solution)).to eq(solution) end end @@ -28,18 +28,18 @@ module Api::V1 context "with valid params" do it "creates a new CommunitySolution" do expect { - post :create, {solution: valid_attributes}, valid_session + post :create, params: { solution: valid_attributes }, session: valid_session }.to change(CommunitySolution, :count).by(1) end it "assigns a newly created solution as @solution" do - post :create, {solution: valid_attributes}, valid_session + post :create, params: { solution: valid_attributes }, session: valid_session expect(assigns(:solution)).to be_a(CommunitySolution) expect(assigns(:solution)).to be_persisted end it "redirects to the created solution" do - post :create, {solution: valid_attributes}, valid_session + post :create, params: { solution: valid_attributes }, session: valid_session expect(response).to redirect_to(CommunitySolution.last) end end @@ -48,14 +48,14 @@ module Api::V1 it "assigns a newly created but unsaved solution as @solution" do # Trigger the behavior that occurs when invalid params are submitted CommunitySolution.any_instance.stub(:save).and_return(false) - post :create, {solution: { "number" => "invalid value" }}, valid_session + post :create, params: { solution: { "number" => "invalid value" } }, session: valid_session expect(assigns(:solution)).to be_a_new(CommunitySolution) end it "re-renders the 'new' template" do # Trigger the behavior that occurs when invalid params are submitted CommunitySolution.any_instance.stub(:save).and_return(false) - post :create, {solution: { "number" => "invalid value" }}, valid_session + post :create, params: { solution: { "number" => "invalid value" } }, session: valid_session expect(response).to render_template("new") end end @@ -70,18 +70,18 @@ module Api::V1 # receives the :update_attributes message with whatever params are # submitted in the request. expect(CommunitySolution.any_instance).to_receive(:update_attributes).with({ "number" => "1" }) - put :update, {id: solution.to_param, solution: { "number" => "1" }}, valid_session + put :update, params: { id: solution.to_param, solution: { "number" => "1" } }, session: valid_session end it "assigns the requested solution as @solution" do solution = CommunitySolution.create! valid_attributes - put :update, {id: solution.to_param, solution: valid_attributes}, valid_session + put :update, params: { id: solution.to_param, solution: valid_attributes }, session: valid_session expect(assigns(:solution)).to eq(solution) end it "redirects to the solution" do solution = CommunitySolution.create! valid_attributes - put :update, {id: solution.to_param, solution: valid_attributes}, valid_session + put :update, params: { id: solution.to_param, solution: valid_attributes }, session: valid_session expect(response).to redirect_to(solution) end end @@ -91,7 +91,7 @@ module Api::V1 solution = CommunitySolution.create! valid_attributes # Trigger the behavior that occurs when invalid params are submitted CommunitySolution.any_instance.stub(:save).and_return(false) - put :update, {id: solution.to_param, solution: { "number" => "invalid value" }}, valid_session + put :update, params: { id: solution.to_param, solution: { "number" => "invalid value" } }, session: valid_session expect(assigns(:solution)).to eq(solution) end @@ -99,7 +99,7 @@ module Api::V1 solution = CommunitySolution.create! valid_attributes # Trigger the behavior that occurs when invalid params are submitted CommunitySolution.any_instance.stub(:save).and_return(false) - put :update, {id: solution.to_param, solution: { "number" => "invalid value" }}, valid_session + put :update, params: { id: solution.to_param, solution: { "number" => "invalid value" } }, session: valid_session expect(response).to render_template("edit") end end @@ -109,13 +109,13 @@ module Api::V1 it "destroys the requested solution" do solution = CommunitySolution.create! valid_attributes expect { - delete :destroy, {id: solution.to_param}, valid_session + delete :destroy, params: { id: solution.to_param }, session: valid_session }.to change(CommunitySolution, :count).by(-1) end it "redirects to the solutions list" do solution = CommunitySolution.create! valid_attributes - delete :destroy, {id: solution.to_param}, valid_session + delete :destroy, params: { id: solution.to_param }, session: valid_session expect(response).to redirect_to(solutions_url) end end diff --git a/spec/controllers/api/v1/deputizations_controller_spec.rb b/spec/controllers/api/v1/deputizations_controller_spec.rb index a1d0e964..176e434d 100644 --- a/spec/controllers/api/v1/deputizations_controller_spec.rb +++ b/spec/controllers/api/v1/deputizations_controller_spec.rb @@ -11,7 +11,7 @@ module Api::V1 context "GET index" do it "assigns all deputizations as @deputizations" do deputization = Deputization.create! valid_attributes - get :index, {}, valid_session + get :index, session: valid_session expect(assigns(:deputizations)).to eq([deputization]) end end @@ -20,18 +20,18 @@ module Api::V1 context "with valid params" do it "creates a new Deputization" do expect { - post :create, {:deputization => valid_attributes}, valid_session + post :create, params: { :deputization => valid_attributes }, session: valid_session }.to change(Deputization, :count).by(1) end it "assigns a newly created deputization as @deputization" do - post :create, {:deputization => valid_attributes}, valid_session + post :create, params: { :deputization => valid_attributes }, session: valid_session expect(assigns(:deputization)).to be_a(Deputization) expect(assigns(:deputization)).to be_persisted end it "redirects to the created deputization" do - post :create, {:deputization => valid_attributes}, valid_session + post :create, params: { :deputization => valid_attributes }, session: valid_session expect(response).to redirect_to(Deputization.last) end end @@ -40,14 +40,14 @@ module Api::V1 it "assigns a newly created but unsaved deputization as @deputization" do # Trigger the behavior that occurs when invalid params are submitted Deputization.any_instance.stub(:save).and_return(false) - post :create, {:deputization => { "number" => "invalid value" }}, valid_session + post :create, params: { :deputization => { "number" => "invalid value" } }, session: valid_session expect(assigns(:deputization)).to be_a_new(Deputization) end it "re-renders the 'new' template" do # Trigger the behavior that occurs when invalid params are submitted Deputization.any_instance.stub(:save).and_return(false) - post :create, {:deputization => { "number" => "invalid value" }}, valid_session + post :create, params: { :deputization => { "number" => "invalid value" } }, session: valid_session expect(response).to render_template("new") end end @@ -57,13 +57,13 @@ module Api::V1 it "destroys the requested deputization" do deputization = Deputization.create! valid_attributes expect { - delete :destroy, {id: deputization.to_param}, valid_session + delete :destroy, params: { id: deputization.to_param }, session: valid_session }.to change(Deputization, :count).by(-1) end it "redirects to the deputizations list" do deputization = Deputization.create! valid_attributes - delete :destroy, {id: deputization.to_param}, valid_session + delete :destroy, params: { id: deputization.to_param }, session: valid_session expect(response).to redirect_to(deputizations_url) end end diff --git a/spec/controllers/api/v1/exercises_controller_spec.rb b/spec/controllers/api/v1/exercises_controller_spec.rb index 19d9c184..e7df9136 100644 --- a/spec/controllers/api/v1/exercises_controller_spec.rb +++ b/spec/controllers/api/v1/exercises_controller_spec.rb @@ -19,9 +19,12 @@ module Api::V1 resource_owner_id: admin.id @exercise = FactoryBot.build(:exercise) - @exercise.publication.authors << FactoryBot.build( + @exercise.publication.authors << FactoryBot.create( :author, user: @user, publication: @exercise.publication ) + @exercise.publication.copyright_holders << FactoryBot.create( + :copyright_holder, user: @user, publication: @exercise.publication + ) @exercise.nickname = 'MyExercise' @exercise.save! end @@ -104,7 +107,7 @@ module Api::V1 context "no matches" do it "does not return drafts that the user is not allowed to see" do - send method, :index, params: {q: 'content:draft'}, format: :json + send method, :index, params: {q: 'content:draft', format: :json} expect(response).to have_http_status(:success) expected_response = { @@ -119,10 +122,10 @@ module Api::V1 context "single match" do it "returns drafts that the user is allowed to see" do @exercise_draft.publication.authors << Author.new(user: @user) - @exercise_draft.publication.reload + @exercise_draft.publication.copyright_holders << CopyrightHolder.new(user: @user) @exercise_draft.reload @user.reload - send method, :index, params: {q: 'content:draft'}, format: :json + send method, :index, params: {q: 'content:draft', format: :json} expect(response).to have_http_status(:success) expected_response = { @@ -134,7 +137,7 @@ module Api::V1 end it "returns an Exercise matching the content" do - send method, :index, params: {q: 'content:"aDiPiScInG eLiT"'}, format: :json + send method, :index, params: {q: 'content:"aDiPiScInG eLiT"', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -146,7 +149,7 @@ module Api::V1 end it "returns an Exercise matching the tags" do - send method, :index, params: {q: 'tag:tAg1'}, format: :json + send method, :index, params: {q: 'tag:tAg1', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -160,7 +163,7 @@ module Api::V1 context "multiple matches" do it "returns Exercises matching the content" do - send method, :index, params: {q: 'content:AdIpIsCi'}, format: :json + send method, :index, params: {q: 'content:AdIpIsCi', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -173,7 +176,7 @@ module Api::V1 end it "returns Exercises matching the tags" do - send method, :index, params: {q: 'tag:TaG2'}, format: :json + send method, :index, params: {q: 'tag:TaG2', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -186,8 +189,8 @@ module Api::V1 end it "sorts by multiple fields in different directions" do - send method, :index, params: {q: 'content:aDiPiScI', order_by: "number DESC, version ASC"}, - format: :json + send method, :index, params: {q: 'content:aDiPiScI', order_by: "number DESC, version ASC", + format: :json } expect(response).to have_http_status(:success) expected_response = { diff --git a/spec/controllers/api/v1/users_controller_spec.rb b/spec/controllers/api/v1/users_controller_spec.rb index afbe4171..9ee07324 100644 --- a/spec/controllers/api/v1/users_controller_spec.rb +++ b/spec/controllers/api/v1/users_controller_spec.rb @@ -28,9 +28,10 @@ module Api::V1 before do 100.times { FactoryBot.create(:user) } - User.joins(:account).where {(account.first_name.like '%doe%') | - (account.last_name.like '%doe%') | - (account.username.like '%doe%')}.delete_all + acc = OpenStax::Accounts::Account.arel_table + User.joins(:account).where(acc[:first_name].matches('%doe%').or( + acc[:last_name].matches('%doe%')).or( + acc[:username].matches('%doe%'))).delete_all @john_doe = FactoryBot.create :user, first_name: "John", last_name: "Doe", diff --git a/spec/controllers/api/v1/vocab_terms_controller_spec.rb b/spec/controllers/api/v1/vocab_terms_controller_spec.rb index 4cc6934c..44733f7e 100644 --- a/spec/controllers/api/v1/vocab_terms_controller_spec.rb +++ b/spec/controllers/api/v1/vocab_terms_controller_spec.rb @@ -38,8 +38,8 @@ module Api::V1 end tested_strings = ["%lorem ipsu%", "%adipiscing elit%", "draft"] - VocabTerm.where {(name.like_any tested_strings) | - (definition.like_any tested_strings)}.delete_all + VocabTerm.where(VocabTerm.arel_table[:name].matches_any(tested_strings).or( + VocabTerm.arel_table[:definition].matches_any(tested_strings))).delete_all @vocab_term_1 = FactoryBot.build(:vocab_term, :published) Api::V1::Vocabs::TermWithDistractorsAndExerciseIdsRepresenter.new( @@ -80,7 +80,7 @@ module Api::V1 context "no matches" do it "does not return drafts that the user is not allowed to see" do - send method, :index, q: 'content:draft', format: :json + send method, :index, params: { q: 'content:draft', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -97,7 +97,7 @@ module Api::V1 @vocab_term_draft.publication.authors << Author.new(user: @user) @vocab_term_draft.reload @user.reload - send method, :index, q: 'content:draft', format: :json + send method, :index, params: { q: 'content:draft', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -109,7 +109,7 @@ module Api::V1 end it "returns a VocabTerm matching the content" do - send method, :index, q: 'content:"oLoReM iPsU"', format: :json + send method, :index, params: { q: 'content:"oLoReM iPsU"', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -121,7 +121,7 @@ module Api::V1 end it "returns a VocabTerm matching the tags" do - send method, :index, q: 'tag:tAg1', format: :json + send method, :index, params: { q: 'tag:tAg1', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -135,7 +135,7 @@ module Api::V1 context "multiple matches" do it "returns VocabTerms matching the content" do - send method, :index, q: 'content:"lOrEm IpSuM"', format: :json + send method, :index, params: { q: 'content:"lOrEm IpSuM"', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -148,7 +148,7 @@ module Api::V1 end it "returns VocabTerms matching the tags" do - send method, :index, q: 'tag:TaG2', format: :json + send method, :index, params: { q: 'tag:TaG2', format: :json } expect(response).to have_http_status(:success) expected_response = { @@ -161,8 +161,8 @@ module Api::V1 end it "sorts by multiple fields in different directions" do - send method, :index, q: 'content:"lOrEm IpSuM"', order_by: "number DESC, version ASC", - format: :json + send method, :index, params: {q: 'content:"lOrEm IpSuM"', order_by: "number DESC, version ASC", + format: :json } expect(response).to have_http_status(:success) expected_response = { From 8291fa9a4f5110cd8711535cb7d3d7c695dc5ce6 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 10:51:29 -0500 Subject: [PATCH 14/50] update expected for school_type field --- .../api/v1/users_controller_spec.rb | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/spec/controllers/api/v1/users_controller_spec.rb b/spec/controllers/api/v1/users_controller_spec.rb index 9ee07324..7b04dbca 100644 --- a/spec/controllers/api/v1/users_controller_spec.rb +++ b/spec/controllers/api/v1/users_controller_spec.rb @@ -73,7 +73,8 @@ module Api::V1 self_reported_role: @john_doe.role, uuid: @john_doe.uuid, support_identifier: @john_doe.support_identifier, - is_test: true + is_test: true, + school_type: 'unknown_school_type' } ] } @@ -99,7 +100,8 @@ module Api::V1 self_reported_role: @jane_doe.role, uuid: @jane_doe.uuid, support_identifier: @jane_doe.support_identifier, - is_test: true + is_test: true, + school_type: 'unknown_school_type' }, { id: @john_doe.account.openstax_uid, @@ -112,7 +114,9 @@ module Api::V1 self_reported_role: @john_doe.role, uuid: @john_doe.uuid, support_identifier: @john_doe.support_identifier, - is_test: true + is_test: true, + school_type: 'unknown_school_type' + } ] } @@ -139,7 +143,9 @@ module Api::V1 self_reported_role: @john_doe.role, uuid: @john_doe.uuid, support_identifier: @john_doe.support_identifier, - is_test: true + is_test: true, + school_type: 'unknown_school_type' + }, { id: @jane_doe.account.openstax_uid, @@ -152,7 +158,9 @@ module Api::V1 self_reported_role: @jane_doe.role, uuid: @jane_doe.uuid, support_identifier: @jane_doe.support_identifier, - is_test: true + is_test: true, + school_type: 'unknown_school_type' + } ] } From 38ae4404a373d18ff76c0cdfce6584c9372afad3 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 11:20:03 -0500 Subject: [PATCH 15/50] fix edit typo --- spec/controllers/oauth/applications_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb index d406ccbb..c497c5d5 100644 --- a/spec/controllers/oauth/applications_controller_spec.rb +++ b/spec/controllers/oauth/applications_controller_spec.rb @@ -84,7 +84,7 @@ module Oauth end it "assigns a newly created application as @application" do - post :create, params: {doorkeeper_application: valid_attributes}, session: dmin_session + post :create, params: {doorkeeper_application: valid_attributes}, session: admin_session expect(assigns(:application)).to be_a(Doorkeeper::Application) expect(assigns(:application)).to be_persisted end From 8a79bf9c88d71a2af574e17c057c10d70ec70e15 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 12:33:28 -0500 Subject: [PATCH 16/50] file needs to be inside params, I think --- spec/controllers/api/v1/attachments_controller_spec.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/controllers/api/v1/attachments_controller_spec.rb b/spec/controllers/api/v1/attachments_controller_spec.rb index 160ad863..02e9589c 100644 --- a/spec/controllers/api/v1/attachments_controller_spec.rb +++ b/spec/controllers/api/v1/attachments_controller_spec.rb @@ -28,6 +28,9 @@ module Api::V1 exercise.publication.authors << FactoryBot.build( :author, user: user, publication: exercise.publication ) + exercise.publication.copyright_holders << FactoryBot.build( + :copyright_holder, user: user, publication: exercise.publication + ) exercise.save! exercise end @@ -46,7 +49,7 @@ module Api::V1 it 'attaches a file to an exercise' do expect do - api_post :create, user_token, params: { exercise_id: exercise_id }, file: image + api_post :create, user_token, params: { exercise_id: exercise_id, file: image } end.to change{ exercise.attachments.count }.by(1) expect(response).to have_http_status(:success) end @@ -54,7 +57,7 @@ module Api::V1 it 'creates a draft if needed' do exercise.publication.publish.save! expect do - api_post :create, user_token, params: { exercise_id: exercise_id }, file: image + api_post :create, user_token, params: { exercise_id: exercise_id, file: image } end.to change{ exercise.publication_group.reload.latest_version }.from(1).to(2) expect(response).to have_http_status(:success) end From c2d7eeb740ce75dca569a7bc7d8c4fc64591e526 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 12:47:37 -0500 Subject: [PATCH 17/50] add more copyright_holders --- .../api/v1/exercises_controller_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/controllers/api/v1/exercises_controller_spec.rb b/spec/controllers/api/v1/exercises_controller_spec.rb index e7df9136..1ad08fa1 100644 --- a/spec/controllers/api/v1/exercises_controller_spec.rb +++ b/spec/controllers/api/v1/exercises_controller_spec.rb @@ -7,6 +7,7 @@ module Api::V1 application = FactoryBot.create :doorkeeper_application @user = FactoryBot.create :user, :agreed_to_terms + @user_1 = FactoryBot.create :user, :agreed_to_terms admin = FactoryBot.create :user, :administrator, :agreed_to_terms @application_token = FactoryBot.create :doorkeeper_access_token, application: application, @@ -67,6 +68,12 @@ module Api::V1 'formats' => [ 'multiple-choice', 'free-response' ] }] ) + @exercise_1.publication.authors << FactoryBot.create( + :author, user: @user_1, publication: @exercise_1.publication + ) + @exercise_1.publication.copyright_holders << FactoryBot.create( + :copyright_holder, user: @user_1, publication: @exercise_1.publication + ) @exercise_1.save! @exercise_2 = FactoryBot.build(:exercise, :published) @@ -83,6 +90,12 @@ module Api::V1 'formats' => [ 'multiple-choice', 'free-response' ] }] ) + @exercise_2.publication.authors << FactoryBot.create( + :author, user: @user_1, publication: @exercise_2.publication + ) + @exercise_2.publication.copyright_holders << FactoryBot.create( + :copyright_holder, user: @user_1, publication: @exercise_2.publication + ) @exercise_2.save! @exercise_draft = FactoryBot.build(:exercise) @@ -419,6 +432,9 @@ module Api::V1 exercise.publication.authors << FactoryBot.build( :author, user: @user, publication: @exercise.publication ) + exercise.publication.copyright_holders << FactoryBot.build( + :copyright_holder, user: @user, publication: @exercise.publication + ) expect do api_post :create, @user_token, body: Api::V1::Exercises::Representer.new( From e277c9d7f6af4f98fc1c55cbf36e2ea022cd67e6 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 12:49:10 -0500 Subject: [PATCH 18/50] upgrade past security issue --- Gemfile | 3 ++- Gemfile.lock | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index a9b381f5..6e0afe29 100644 --- a/Gemfile +++ b/Gemfile @@ -59,7 +59,8 @@ gem 'openstax_utilities' gem 'whenever' # Talks to Accounts (latest version is broken) -gem 'omniauth-oauth2', '~> 1.3.1' +# gem 'omniauth-oauth2', '~> 1.3.1' +gem 'omniauth-oauth2' # OpenStax Accounts integration gem 'openstax_accounts' diff --git a/Gemfile.lock b/Gemfile.lock index 05022c2d..bbfe7bdc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -254,9 +254,9 @@ GEM omniauth (1.9.0) hashie (>= 3.4.6, < 3.7.0) rack (>= 1.6.2, < 3) - omniauth-oauth2 (1.3.1) - oauth2 (~> 1.0) - omniauth (~> 1.2) + omniauth-oauth2 (1.6.0) + oauth2 (~> 1.1) + omniauth (~> 1.9) openstax_accounts (8.0.0) action_interceptor keyword_search @@ -538,7 +538,7 @@ DEPENDENCIES nifty-generators oj oj_mimic_json - omniauth-oauth2 (~> 1.3.1) + omniauth-oauth2 openstax_accounts openstax_api openstax_healthcheck From 89fc7046ff68c6b368ad1ea9b5b9f3fcbcb547ce Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 13:51:10 -0500 Subject: [PATCH 19/50] more copyright_holders --- .../api/v1/publications_controller_spec.rb | 10 ++++++++++ .../controllers/api/v1/vocab_terms_controller_spec.rb | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/spec/controllers/api/v1/publications_controller_spec.rb b/spec/controllers/api/v1/publications_controller_spec.rb index 8254bc34..0e6a34d4 100644 --- a/spec/controllers/api/v1/publications_controller_spec.rb +++ b/spec/controllers/api/v1/publications_controller_spec.rb @@ -17,6 +17,16 @@ module Api::V1 FactoryBot.create :author, publication: solution.publication } + let(:exercise_copyright_holder) { + FactoryBot.create :copyright_holder, publication: exercise.publication + } + let(:vocab_term_copyright_holder) { + FactoryBot.create :copyright_holder, publication: vocab_term.publication + } + let(:solution_copyright_holder) { + FactoryBot.create :copyright_holder, publication: solution.publication + } + let(:exercise_author_token) { FactoryBot.create :doorkeeper_access_token, resource_owner_id: exercise_author.user_id diff --git a/spec/controllers/api/v1/vocab_terms_controller_spec.rb b/spec/controllers/api/v1/vocab_terms_controller_spec.rb index 44733f7e..31cd2176 100644 --- a/spec/controllers/api/v1/vocab_terms_controller_spec.rb +++ b/spec/controllers/api/v1/vocab_terms_controller_spec.rb @@ -22,6 +22,9 @@ module Api::V1 @vocab_term.publication.authors << FactoryBot.build( :author, user: @user, publication: @vocab_term.publication ) + @vocab_term.publication.copyright_holders << FactoryBot.build( + :copyright_holder, user: @user, publication: @vocab_term.publication + ) @vocab_term.nickname = 'MyVocab' @vocab_term.save! end @@ -35,6 +38,7 @@ module Api::V1 10.times do vt = FactoryBot.create(:vocab_term, :published) vt.publication.authors << Author.new(publication: vt.publication, user: @user) + vt.publication.copyright_holders << CopyrightHolder.new(publication: vt.publication, user: @user) end tested_strings = ["%lorem ipsu%", "%adipiscing elit%", "draft"] @@ -50,6 +54,8 @@ module Api::V1 'definition' => "Dolor sit amet", 'distractor_literals' => ["Consectetur adipiscing elit", "Sed do eiusmod tempor"] ) + @vocab_term_1.publication.authors << Author.new(publication: @vocab_term_1.publication, user: @user) + @vocab_term_1.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_1.publication, user: @user) @vocab_term_1.save! @vocab_term_2 = FactoryBot.build(:vocab_term, :published) @@ -61,6 +67,8 @@ module Api::V1 'definition' => "Quia dolor sit amet", 'distractor_literals' => ["Consectetur adipisci velit", "Sed quia non numquam"] ) + @vocab_term_2.publication.authors << Author.new(publication: @vocab_term_2.publication, user: @user) + @vocab_term_2.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_2.publication, user: @user) @vocab_term_2.save! @vocab_term_draft = FactoryBot.build(:vocab_term) @@ -72,6 +80,8 @@ module Api::V1 'definition' => "Not ready for prime time", 'distractor_literals' => ["Release to production NOW"] ) + @vocab_term_draft.publication.authors << Author.new(publication: @vocab_term_draft.publication, user: @user) + @vocab_term_draft.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_draft.publication, user: @user) @vocab_term_draft.save! end after(:all) { DatabaseCleaner.clean } @@ -95,6 +105,7 @@ module Api::V1 context "single match" do it "returns drafts that the user is allowed to see" do @vocab_term_draft.publication.authors << Author.new(user: @user) + @vocab_term_draft.publication.copyright_holders << CopyrightHolder.new(user: @user) @vocab_term_draft.reload @user.reload send method, :index, params: { q: 'content:draft', format: :json } From 619b78ab0377d1b414ee94fbd9f073cef1860f2c Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 15:55:44 -0500 Subject: [PATCH 20/50] fix with_id fetching --- lib/publishable/active_record.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/publishable/active_record.rb b/lib/publishable/active_record.rb index 94eb154a..af2abf54 100644 --- a/lib/publishable/active_record.rb +++ b/lib/publishable/active_record.rb @@ -34,13 +34,13 @@ def publishable(options = {}) wheres = pubg[:uuid].eq(nn).or(pubg[:number].eq(nn)) case vv when NilClass - wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) + wheres = wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) when 'draft', 'd' - wheres.and(pub[:published_at].not_eq(nil)) + wheres = wheres.and(pub[:published_at].eq(nil)) when 'latest' wheres else - wheres.and(pub[:version].eq(vv)) + wheres = wheres.and(pub[:version].eq(vv)) end joins(publication: :publication_group).where(wheres From e614154b9537d2b11c0d3088839ccbc6910ab975 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 31 May 2019 16:05:50 -0500 Subject: [PATCH 21/50] need at least one author and one copyright_holder --- spec/controllers/api/v1/exercises_controller_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/controllers/api/v1/exercises_controller_spec.rb b/spec/controllers/api/v1/exercises_controller_spec.rb index 1ad08fa1..cb7c241b 100644 --- a/spec/controllers/api/v1/exercises_controller_spec.rb +++ b/spec/controllers/api/v1/exercises_controller_spec.rb @@ -362,6 +362,13 @@ module Api::V1 it "hides solutions for published exercises if the requestor is not allowed to edit it" do @exercise.publication.authors.destroy_all + @exercise.publication.copyright_holders.destroy_all + @exercise.publication.authors << FactoryBot.create( + :author, user: @user_1, publication: @exercise.publication + ) + @exercise.publication.copyright_holders << FactoryBot.create( + :copyright_holder, user: @user_1, publication: @exercise.publication + ) api_get :show, @user_token, params: { id: @exercise.uid } expect(response).to have_http_status(:success) From b26f04e3ee8f600b9c5c3155e8450965a3a7f471 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 3 Jun 2019 10:09:54 -0500 Subject: [PATCH 22/50] Use Rack file uploader --- spec/controllers/api/v1/attachments_controller_spec.rb | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/spec/controllers/api/v1/attachments_controller_spec.rb b/spec/controllers/api/v1/attachments_controller_spec.rb index 02e9589c..24321051 100644 --- a/spec/controllers/api/v1/attachments_controller_spec.rb +++ b/spec/controllers/api/v1/attachments_controller_spec.rb @@ -40,11 +40,8 @@ module Api::V1 context "POST create" do let(:image) { - image = ActionDispatch::Http::UploadedFile.new( - filename: 'test_photo_1.jpg', - type: 'image/jpeg', - tempfile: File.new("#{Rails.root}/spec/fixtures/rails.png") - ) + image = Rack::Test::UploadedFile.new("#{Rails.root}/spec/fixtures/rails.png", + 'image/jpeg') } it 'attaches a file to an exercise' do From d833547fcd6d3edb6da394b44a6a45c85efedb91 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 3 Jun 2019 10:37:14 -0500 Subject: [PATCH 23/50] fix the _other_ with_id scope --- app/models/publication.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/publication.rb b/app/models/publication.rb index fb3492d1..5f1deac4 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -45,13 +45,13 @@ class Publication < ApplicationRecord wheres = pubg[:uuid].eq(nn).or(pubg[:number].eq(nn)) case vv when NilClass - wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) + wheres = wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) when 'draft', 'd' - wheres.and(pub[:published_at].not_eq(nil)) + wheres = wheres.and(pub[:published_at].eq(nil)) when 'latest' wheres else - wheres.and(pub[:version].eq(vv)) + wheres = wheres.and(pub[:version].eq(vv)) end joins(publication: :publication_group).where(wheres From 1f649f40e86a1a7fc5344175b88d7116c0929d79 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 3 Jun 2019 11:19:22 -0500 Subject: [PATCH 24/50] more author and copyright_holder setup fixes --- .../api/v1/publications_controller_spec.rb | 12 ++++++------ .../api/v1/vocab_terms_controller_spec.rb | 15 +++++++++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/spec/controllers/api/v1/publications_controller_spec.rb b/spec/controllers/api/v1/publications_controller_spec.rb index 0e6a34d4..cffd9950 100644 --- a/spec/controllers/api/v1/publications_controller_spec.rb +++ b/spec/controllers/api/v1/publications_controller_spec.rb @@ -7,23 +7,23 @@ module Api::V1 let(:vocab_term) { FactoryBot.create :vocab_term } let(:solution) { FactoryBot.create :community_solution } - let(:exercise_author) { + let!(:exercise_author) { FactoryBot.create :author, publication: exercise.publication } - let(:vocab_term_author) { + let!(:vocab_term_author) { FactoryBot.create :author, publication: vocab_term.publication } - let(:solution_author) { + let!(:solution_author) { FactoryBot.create :author, publication: solution.publication } - let(:exercise_copyright_holder) { + let!(:exercise_copyright_holder) { FactoryBot.create :copyright_holder, publication: exercise.publication } - let(:vocab_term_copyright_holder) { + let!(:vocab_term_copyright_holder) { FactoryBot.create :copyright_holder, publication: vocab_term.publication } - let(:solution_copyright_holder) { + let!(:solution_copyright_holder) { FactoryBot.create :copyright_holder, publication: solution.publication } diff --git a/spec/controllers/api/v1/vocab_terms_controller_spec.rb b/spec/controllers/api/v1/vocab_terms_controller_spec.rb index 31cd2176..1336ef4e 100644 --- a/spec/controllers/api/v1/vocab_terms_controller_spec.rb +++ b/spec/controllers/api/v1/vocab_terms_controller_spec.rb @@ -7,6 +7,9 @@ module Api::V1 application = FactoryBot.create :doorkeeper_application @user = FactoryBot.create :user, :agreed_to_terms + @user_1 = FactoryBot.create :user, :agreed_to_terms + @user_2 = FactoryBot.create :user, :agreed_to_terms + @user_draft = FactoryBot.create :user, :agreed_to_terms admin = FactoryBot.create :user, :administrator, :agreed_to_terms @application_token = FactoryBot.create :doorkeeper_access_token, application: application, @@ -54,8 +57,8 @@ module Api::V1 'definition' => "Dolor sit amet", 'distractor_literals' => ["Consectetur adipiscing elit", "Sed do eiusmod tempor"] ) - @vocab_term_1.publication.authors << Author.new(publication: @vocab_term_1.publication, user: @user) - @vocab_term_1.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_1.publication, user: @user) + @vocab_term_1.publication.authors << Author.new(publication: @vocab_term_1.publication, user: @user_1) + @vocab_term_1.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_1.publication, user: @user_1) @vocab_term_1.save! @vocab_term_2 = FactoryBot.build(:vocab_term, :published) @@ -67,8 +70,8 @@ module Api::V1 'definition' => "Quia dolor sit amet", 'distractor_literals' => ["Consectetur adipisci velit", "Sed quia non numquam"] ) - @vocab_term_2.publication.authors << Author.new(publication: @vocab_term_2.publication, user: @user) - @vocab_term_2.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_2.publication, user: @user) + @vocab_term_2.publication.authors << Author.new(publication: @vocab_term_2.publication, user: @user_2) + @vocab_term_2.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_2.publication, user: @user_2) @vocab_term_2.save! @vocab_term_draft = FactoryBot.build(:vocab_term) @@ -80,8 +83,8 @@ module Api::V1 'definition' => "Not ready for prime time", 'distractor_literals' => ["Release to production NOW"] ) - @vocab_term_draft.publication.authors << Author.new(publication: @vocab_term_draft.publication, user: @user) - @vocab_term_draft.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_draft.publication, user: @user) + @vocab_term_draft.publication.authors << Author.new(publication: @vocab_term_draft.publication, user: @user_draft) + @vocab_term_draft.publication.copyright_holders << CopyrightHolder.new(publication: @vocab_term_draft.publication, user: @user_draft) @vocab_term_draft.save! end after(:all) { DatabaseCleaner.clean } From 2dff70927bff0ef1359d4e9bb29e7eea7e4675cd Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 3 Jun 2019 16:56:57 -0500 Subject: [PATCH 25/50] mostly import de-squeel --- app/models/administrator.rb | 2 +- app/models/attachment.rb | 1 + app/routines/exercises/import/old/row_importer.rb | 12 ++++++------ app/routines/exercises/import/quadbase.rb | 4 ++-- config/initializers/new_framework_defaults.rb | 2 +- lib/exercises/importer.rb | 11 ++++++----- lib/vocab_terms/importer.rb | 9 ++++----- 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/app/models/administrator.rb b/app/models/administrator.rb index 85cc0f73..89d2f256 100644 --- a/app/models/administrator.rb +++ b/app/models/administrator.rb @@ -2,6 +2,6 @@ class Administrator < ApplicationRecord belongs_to :user - validates :user, uniqueness: true + validates :user, presence: true, uniqueness: true end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 74ac5b8e..90cfc2b3 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -7,6 +7,7 @@ class Attachment < ApplicationRecord before_update { raise ActiveRecord::ReadOnlyRecord } # Prevent updates validates :asset, presence: true + validates :parent, presence: true validate :unique_asset def filename diff --git a/app/routines/exercises/import/old/row_importer.rb b/app/routines/exercises/import/old/row_importer.rb index 89731324..76adfe8a 100644 --- a/app/routines/exercises/import/old/row_importer.rb +++ b/app/routines/exercises/import/old/row_importer.rb @@ -69,12 +69,12 @@ def perform_row_import(row, index) dok_tag, time_tag, display_type_tags, blooms_tag].flatten.uniq ex.tags = tags - latest_exercise = Exercise - .joins([{publication: :publication_group}, {exercise_tags: :tag}]) - .where(exercise_tags: {tag: {name: exercise_id_tag}}) - .order {[publication.publication_group.number.desc, publication.version.desc]}.first + pub = Publication.arel_table + pubg = PublicationGroup.arel_table - unless latest_exercise.nil? + latest_exercise = Exercise.joins([{publication: :publication_group}, {exercise_tags: :tag}]).where(exercise_tags: {tag: {name: exercise_id_tag}}).order ([pubg[:number].desc, pub[:version].desc]).first + + unless latest_exercise.empty? ex.publication.publication_group = latest_exercise.publication.publication_group ex.publication.version = latest_exercise.publication.version + 1 end @@ -172,7 +172,7 @@ def perform_row_import(row, index) row = "Imported row ##{index + 1}" uid = skipped ? "Existing uid: #{latest_exercise.uid}" : "New uid: #{ex.uid}" changes = skipped ? "Exercise skipped (no changes)" : \ - "New #{latest_exercise.nil? ? 'exercise' : 'version'}" + "New #{latest_exercise.empty? ? 'exercise' : 'version'}" Rails.logger.info "#{row} - #{uid} - #{changes}" end diff --git a/app/routines/exercises/import/quadbase.rb b/app/routines/exercises/import/quadbase.rb index 89952e72..ac1a7b30 100644 --- a/app/routines/exercises/import/quadbase.rb +++ b/app/routines/exercises/import/quadbase.rb @@ -45,7 +45,7 @@ def import_question(hash) publication = import_metadata(exercise.publication, hash['attribution']) - unless latest_exercise.nil? + unless latest_exercise.empty? publication.publication_group = latest_exercise.publication.publication_group publication.version = latest_exercise.publication.version + 1 end @@ -88,7 +88,7 @@ def import_question(hash) ex = "Imported Exercise #{hash['id']}" uid = skipped ? "Existing uid: #{latest_exercise.uid}" : "New uid: #{exercise.uid}" changes = skipped ? "Exercise skipped (no changes)" : \ - "New #{latest_exercise.nil? ? 'exercise' : 'version'}" + "New #{latest_exercise.empty? ? 'exercise' : 'version'}" Rails.logger.info "#{ex} - #{uid} - #{changes}" end diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb index cbf423a8..c94b4e8c 100644 --- a/config/initializers/new_framework_defaults.rb +++ b/config/initializers/new_framework_defaults.rb @@ -19,7 +19,7 @@ ActiveSupport.to_time_preserves_timezone = false # Require `belongs_to` associations by default. Previous versions had false. -Rails.application.config.active_record.belongs_to_required_by_default = false +Rails.application.config.active_record.belongs_to_required_by_default = true # Do not halt callback chains when a callback returns false. Previous versions had true. ActiveSupport.halt_callback_chains_on_return_false = true diff --git a/lib/exercises/importer.rb b/lib/exercises/importer.rb index ef0d8ba6..86b6d185 100644 --- a/lib/exercises/importer.rb +++ b/lib/exercises/importer.rb @@ -51,12 +51,13 @@ def import_row(row, row_number) ex.tags = book_tags + lo_tags + type_tags + \ [id_tag, cnxmod_tag, dok_tag, blooms_tag, time_tag] - latest_exercise = Exercise - .joins([{publication: :publication_group}, {exercise_tags: :tag}]) - .where(exercise_tags: {tag: {name: id_tag}}) - .order {[publication.publication_group.number.desc, publication.version.desc]}.first + pub = Publication.arel_table + pubg = PublicationGroup.arel_table - unless latest_exercise.nil? + latest_exercise = Exercise.joins([{publication: :publication_group}, {exercise_tags: :tag}]).where(exercise_tags: {tag: {name: id_tag}}).order ([pubg[:number].desc, pub[:version].desc]).first + + + unless latest_exercise.empty? ex.publication.publication_group = latest_exercise.publication.publication_group ex.publication.version = latest_exercise.publication.version + 1 end diff --git a/lib/vocab_terms/importer.rb b/lib/vocab_terms/importer.rb index cb009e52..39a1f323 100644 --- a/lib/vocab_terms/importer.rb +++ b/lib/vocab_terms/importer.rb @@ -54,11 +54,10 @@ def import_row(row, row_number) @latest_term_map ||= Hash.new do |hash, chapter| hash[chapter] = Hash.new do |hash, name| lo_like = "lo:stax-#{book}:#{chapter}-%" - hash[name] = VocabTerm - .joins([{publication: :publication_group}, {vocab_term_tags: :tag}]) - .where(name: name) - .where {vocab_term_tags.tag.name.like lo_like} - .order {[publication.publication_group.number.desc, publication.version.desc]}.first + ta = Tag.arel_table + pub = Publication.arel_table + pubg = PublicationGroup.arel_table + hash[name] = VocabTerm.joins([{publication: :publication_group}, {vocab_term_tags: :tag}]).where(name: name).where(ta[:name].matches lo_like).order([pubg[:number].desc, pub[:version].desc]).first end end From ec9cef402460964206c65221a980699835c2d832 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Tue, 4 Jun 2019 12:49:50 -0500 Subject: [PATCH 26/50] fixup kramdown math import --- .../exercises/import/old/row_importer.rb | 2 +- config/initializers/kramdown.rb | 82 +++++++++++++++++++ lib/exercises/importer.rb | 2 +- 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 config/initializers/kramdown.rb diff --git a/app/routines/exercises/import/old/row_importer.rb b/app/routines/exercises/import/old/row_importer.rb index 76adfe8a..030d9662 100644 --- a/app/routines/exercises/import/old/row_importer.rb +++ b/app/routines/exercises/import/old/row_importer.rb @@ -17,7 +17,7 @@ def parse(text, exercise) return nil if text.blank? text = text.to_s - kd = Kramdown::Document.new(text.to_s.strip, attachable: exercise) + kd = Kramdown::Document.new(text.to_s.strip, math_engine: :openstax, attachable: exercise) # If only one

tag, remove it and just return the nodes below kd.root.children = kd.root.children.first.children \ if kd.root.children.length == 1 && kd.root.children.first.type == :p diff --git a/config/initializers/kramdown.rb b/config/initializers/kramdown.rb new file mode 100644 index 00000000..27bb7383 --- /dev/null +++ b/config/initializers/kramdown.rb @@ -0,0 +1,82 @@ +# https://www.snip2code.com/Snippet/49311/Monkey-patch-for-Kramdown-to-rewrite-rel +require 'addressable/uri' + +Kramdown::Parser::Kramdown.class_exec do + + def add_link_with_attachments(el, href, title, alt_text = nil, ial = nil) + if Addressable::URI.parse(href).relative? && @options[:attachable] + # href is actually a path to a local file for the spreadsheet importer + outputs = AttachFile.call(attachable: @options[:attachable], file: href).outputs + href = outputs.large_url || outputs.url + end + + add_link_without_attachments(el, href, title, alt_text, ial) + end + alias_method_chain :add_link, :attachments + + SINGLE_DOLLAR_INLINE_MATH_START = /(?" : el.value) + text.gsub!(/<\/?script>?/, '') + + preview = preview_string(converter, el, opts) + + attr = {:'data-math' => text} + if type == :block + preview << converter.format_as_block_html('div', attr, text, opts[:indent]) + else + preview << converter.format_as_span_html('span', attr, text) + end + end + + def self.preview_string(converter, el, opts) + preview = converter.options[:math_engine_opts][:preview] + return '' unless preview + + preview = (preview == true ? converter.escape_html(el.value) : preview.to_s) + + preview_as_code = converter.options[:math_engine_opts][:preview_as_code] + + if el.options[:category] == :block + if preview_as_code + converter.format_as_block_html('pre', {'class' => 'MathJax_Preview'}, + converter.format_as_span_html('code', {}, preview), + opts[:indent]) + else + converter.format_as_block_html('div', {'class' => 'MathJax_Preview'}, preview, + opts[:indent]) + end + else + converter.format_as_span_html(preview_as_code ? 'code' : 'span', + {'class' => 'MathJax_Preview'}, preview) + end + end + + end + + end + + add_math_engine(:openstax, MathEngine::OpenStax) + +end diff --git a/lib/exercises/importer.rb b/lib/exercises/importer.rb index 86b6d185..d37a17a9 100644 --- a/lib/exercises/importer.rb +++ b/lib/exercises/importer.rb @@ -12,7 +12,7 @@ def parse(text, exercise) text = text.to_s - kd = Kramdown::Document.new(text.to_s.strip, attachable: exercise) + kd = Kramdown::Document.new(text.to_s.strip, math_engine: :openstax, attachable: exercise) # If only one

tag, remove it and just return the nodes below kd.root.children = kd.root.children.first.children \ if kd.root.children.length == 1 && kd.root.children.first.type == :p From 9e55a493ccd6bf728a2bdc633b3003cf09d09434 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Tue, 4 Jun 2019 13:33:19 -0500 Subject: [PATCH 27/50] callback chain termination --- app/models/exercise.rb | 2 +- app/models/publication.rb | 2 +- app/models/vocab_term.rb | 3 +-- config/initializers/new_framework_defaults.rb | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 82b038f3..f68ab327 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -138,7 +138,7 @@ def before_publication question.stems.each do |stem| next if stem.stem_answers.empty? || stem.stem_answers.any?{ |sa| sa.is_correct? } errors.add(:base, 'has a question with only incorrect answers') - return false + throw(:abort) end end diff --git a/app/models/publication.rb b/app/models/publication.rb index 5f1deac4..98435b41 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -246,7 +246,7 @@ def before_publication errors.add(publishable_type.underscore.to_sym, message) end - false + throw(:abort) end def after_publication diff --git a/app/models/vocab_term.rb b/app/models/vocab_term.rb index b0b839ec..a28fe476 100644 --- a/app/models/vocab_term.rb +++ b/app/models/vocab_term.rb @@ -111,14 +111,13 @@ def before_publication errors.add(:base, 'must have at least 1 distractor') \ if distractor_literals.empty? && vocab_distractors.empty? - return false if errors.any? + throw(:abort) if errors.any? # Publish exercises latest_exercises.each do |exercise| exercise.publication.update_attribute :published_at, published_at end - true end def after_publication diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb index c94b4e8c..fea40a14 100644 --- a/config/initializers/new_framework_defaults.rb +++ b/config/initializers/new_framework_defaults.rb @@ -22,4 +22,4 @@ Rails.application.config.active_record.belongs_to_required_by_default = true # Do not halt callback chains when a callback returns false. Previous versions had true. -ActiveSupport.halt_callback_chains_on_return_false = true +ActiveSupport.halt_callback_chains_on_return_false = false From a8a332693c2281f77c03132ffde2a8c20860ecb1 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Tue, 4 Jun 2019 15:23:33 -0500 Subject: [PATCH 28/50] fix attachment unique_asset test --- app/models/attachment.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 90cfc2b3..9cea9089 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -23,11 +23,9 @@ def remove_asset! def unique_asset return if asset.nil? || parent.nil? at = Attachment.arel_table - return unless Attachment.where((at[:id] != id) & \ - (at[:parent] == parent) & \ - (at[:asset] == asset.identifier)).exists? + return unless Attachment.where(at[:id].not_eq(id).and(at[:parent_id].eq(parent.id)).and(at[:asset].eq(asset.identifier))).exists? errors.add(:asset, 'has already been associated with this resource') - false + throw(:abort) end end From abb5fb624b4769056b9ea6bf085263719d74fc18 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Tue, 4 Jun 2019 15:24:43 -0500 Subject: [PATCH 29/50] throw (and expect) abort --- app/models/exercise.rb | 4 +--- app/models/publication.rb | 11 +++++++---- spec/models/exercise_spec.rb | 4 ++-- spec/models/vocab_term_spec.rb | 4 ++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/models/exercise.rb b/app/models/exercise.rb index f68ab327..2710197e 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -141,8 +141,6 @@ def before_publication throw(:abort) end end - - true end protected @@ -150,7 +148,7 @@ def before_publication def has_questions return unless questions.first.nil? errors.add(:questions, "can't be blank") - false + throw(:abort) end end diff --git a/app/models/publication.rb b/app/models/publication.rb index 98435b41..75561fcc 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -220,7 +220,7 @@ def valid_license return if license.nil? || license.valid_for?(publishable_type) errors.add(:license, "is invalid for #{publishable_type}") - false + throw(:abort) end def valid_publication_group @@ -233,13 +233,16 @@ def valid_publication_group errors.add(:publication_group, "is invalid for #{publishable_type}") \ if publication_group.publishable_type != publishable_type publication_group.errors.each { |attribute, error| errors.add attribute, error } - false + throw(:abort) end def before_publication return if published_at.nil? || publishable.nil? - publishable.before_publication + catch(:abort) do + publishable.before_publication + end + return if publishable.errors.empty? publishable.errors.full_messages.each do |message| @@ -265,7 +268,7 @@ def after_publication errors.add(publishable_type.underscore.to_sym, message) end - false + throw(:abort) end end diff --git a/spec/models/exercise_spec.rb b/spec/models/exercise_spec.rb index 7f9a75e6..ce1cdc68 100644 --- a/spec/models/exercise_spec.rb +++ b/spec/models/exercise_spec.rb @@ -14,7 +14,7 @@ expect(exercise.errors).to be_empty exercise.questions = [] - exercise.send :has_questions + expect { exercise.send :has_questions }.to throw_symbol(:abort) expect(exercise.errors[:questions]).to include("can't be blank") end @@ -26,7 +26,7 @@ exercise.questions.first.stems.first.stem_answers.each do |stem_answer| stem_answer.update_attribute :correctness, 0.0 end - exercise.before_publication + expect { exercise.before_publication }.to throw_symbol(:abort) expect(exercise.errors[:base]).to include('has a question with only incorrect answers') end diff --git a/spec/models/vocab_term_spec.rb b/spec/models/vocab_term_spec.rb index 7c4a544d..01be958b 100644 --- a/spec/models/vocab_term_spec.rb +++ b/spec/models/vocab_term_spec.rb @@ -24,7 +24,7 @@ expect(vocab_term.errors).to be_empty vocab_term.definition = '' - vocab_term.before_publication + expect { vocab_term.before_publication }.to throw_symbol(:abort) expect(vocab_term.errors[:base]).to include('must have a definition') end @@ -39,7 +39,7 @@ expect(vocab_term.errors).to be_empty vocab_term.distractor_literals = [] - vocab_term.before_publication + expect { vocab_term.before_publication }.to throw_symbol(:abort) expect(vocab_term.errors[:base]).to include('must have at least 1 distractor') end From 520f1861bdcf969a72dc69b331fe8aba2a381b4f Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Tue, 4 Jun 2019 16:33:49 -0500 Subject: [PATCH 30/50] fixup weirdness w/ empty return sets --- app/routines/exercises/import/quadbase.rb | 8 ++++---- lib/exercises/importer.rb | 7 +++++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/routines/exercises/import/quadbase.rb b/app/routines/exercises/import/quadbase.rb index ac1a7b30..3427fb58 100644 --- a/app/routines/exercises/import/quadbase.rb +++ b/app/routines/exercises/import/quadbase.rb @@ -40,12 +40,12 @@ def import_question(hash) pubg = PublicationGroup.arel_table latest_exercise = Exercise .joins([{publication: :publication_group}, {exercise_tags: :tag}]) - .where(exercise_tags: {tag: {name: id_tag}} - ).order(pubg[:number].desc, pub[:version].desc).first + .where(exercise_tags: {tag: {name: id_tag}}) + .order(pubg[:number].desc, pub[:version].desc).first publication = import_metadata(exercise.publication, hash['attribution']) - unless latest_exercise.empty? + unless latest_exercise.nil? publication.publication_group = latest_exercise.publication.publication_group publication.version = latest_exercise.publication.version + 1 end @@ -88,7 +88,7 @@ def import_question(hash) ex = "Imported Exercise #{hash['id']}" uid = skipped ? "Existing uid: #{latest_exercise.uid}" : "New uid: #{exercise.uid}" changes = skipped ? "Exercise skipped (no changes)" : \ - "New #{latest_exercise.empty? ? 'exercise' : 'version'}" + "New #{latest_exercise.nil? ? 'exercise' : 'version'}" Rails.logger.info "#{ex} - #{uid} - #{changes}" end diff --git a/lib/exercises/importer.rb b/lib/exercises/importer.rb index d37a17a9..ee9672a4 100644 --- a/lib/exercises/importer.rb +++ b/lib/exercises/importer.rb @@ -54,10 +54,13 @@ def import_row(row, row_number) pub = Publication.arel_table pubg = PublicationGroup.arel_table - latest_exercise = Exercise.joins([{publication: :publication_group}, {exercise_tags: :tag}]).where(exercise_tags: {tag: {name: id_tag}}).order ([pubg[:number].desc, pub[:version].desc]).first + latest_exercise = Exercise + .joins([{publication: :publication_group}, {exercise_tags: :tag}]) + .where(exercise_tags: {tag: {name: id_tag}}) + .order([pubg[:number].desc, pub[:version].desc]).first - unless latest_exercise.empty? + unless latest_exercise.nil? ex.publication.publication_group = latest_exercise.publication.publication_group ex.publication.version = latest_exercise.publication.version + 1 end From ee3287925e01269020d03c846395f8f37484337d Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Wed, 5 Jun 2019 13:39:52 -0500 Subject: [PATCH 31/50] tag migrations with version --- db/migrate/20140724183731_create_doorkeeper_tables.rb | 2 +- db/migrate/20140724183732_add_owner_to_application.rb | 2 +- db/migrate/20140724183745_acts_as_votable_migration.rb | 2 +- db/migrate/20140724183919_install_commontator.rb | 2 +- db/migrate/20140724183932_install_fine_print.rb | 2 +- db/migrate/20140724184012_create_openstax_accounts_accounts.rb | 2 +- ...4184013_create_openstax_accounts_groups.openstax_accounts.rb | 2 +- ..._create_openstax_accounts_group_members.openstax_accounts.rb | 2 +- ...5_create_openstax_accounts_group_owners.openstax_accounts.rb | 2 +- ...create_openstax_accounts_group_nestings.openstax_accounts.rb | 2 +- db/migrate/20140724184630_create_users.rb | 2 +- db/migrate/20140724184800_create_administrators.rb | 2 +- db/migrate/20140724184944_create_exercises.rb | 2 +- db/migrate/20140724185123_create_questions.rb | 2 +- db/migrate/20140724185227_create_stems.rb | 2 +- db/migrate/20140724203302_create_stylings.rb | 2 +- db/migrate/20140724204932_create_answers.rb | 2 +- db/migrate/20140724211735_create_combo_choices.rb | 2 +- db/migrate/20140724211804_create_combo_choice_answers.rb | 2 +- db/migrate/20140728144750_create_solutions.rb | 2 +- db/migrate/20140728145131_create_derivations.rb | 2 +- db/migrate/20140728145209_create_licenses.rb | 2 +- db/migrate/20140728145518_create_question_dependencies.rb | 2 +- db/migrate/20140728180028_create_lists.rb | 2 +- db/migrate/20140728191217_create_list_exercises.rb | 2 +- db/migrate/20140728193853_create_attachments.rb | 2 +- db/migrate/20140728222603_create_logics.rb | 2 +- db/migrate/20140728223106_create_logic_variables.rb | 2 +- db/migrate/20140728223606_create_logic_variable_values.rb | 2 +- db/migrate/20140819211115_create_deputizations.rb | 2 +- db/migrate/20140821185536_create_list_owners.rb | 2 +- db/migrate/20140821185603_create_list_editors.rb | 2 +- db/migrate/20140821185624_create_list_readers.rb | 2 +- db/migrate/20140822204013_create_publications.rb | 2 +- db/migrate/20140827193017_create_license_compatibilities.rb | 2 +- db/migrate/20140827221742_create_list_nestings.rb | 2 +- db/migrate/20140828151517_create_class_licenses.rb | 2 +- db/migrate/20140904205107_create_trusted_applications.rb | 2 +- db/migrate/20140916214330_create_editors.rb | 2 +- db/migrate/20140916214350_create_authors.rb | 2 +- db/migrate/20140916214406_create_copyright_holders.rb | 2 +- db/migrate/20141107194147_create_stem_answers.rb | 2 +- db/migrate/20141118174146_create_hints.rb | 2 +- db/migrate/20150225002223_create_tags.rb | 2 +- db/migrate/20150225002247_create_exercise_tags.rb | 2 +- db/migrate/20160212204251_add_sort_position_to_answers.rb | 2 +- .../20160212211016_add_answer_order_matters_to_questions.rb | 2 +- ...20160226221827_rename_solutions_to_collaborator_solutions.rb | 2 +- db/migrate/20160226222403_create_community_solutions.rb | 2 +- db/migrate/20160406202802_add_sort_position_to_questions.rb | 2 +- db/migrate/20160413220455_create_vocab_terms.rb | 2 +- db/migrate/20160413220518_create_vocab_distractors.rb | 2 +- db/migrate/20160413222116_remove_duplicate_indices.rb | 2 +- db/migrate/20160413223442_add_vocab_term_id_to_exercises.rb | 2 +- db/migrate/20160420172854_create_vocab_term_tags.rb | 2 +- ...18_change_questions_answer_order_matters_default_to_false.rb | 2 +- db/migrate/20160425191417_create_list_vocab_terms.rb | 2 +- .../20160606214816_add_default_to_vocab_terms_definition.rb | 2 +- db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb | 2 +- db/migrate/20160922220434_create_publication_groups.rb | 2 +- ...231345_change_publications_number_to_publication_group_id.rb | 2 +- db/migrate/20161006223624_add_uuid_to_publications.rb | 2 +- db/migrate/20161019223527_create_list_publication_groups.rb | 2 +- ...exercises_and_list_vocab_terms_to_list_publication_groups.rb | 2 +- ...distractor_term_number_to_distractor_publication_group_id.rb | 2 +- db/migrate/20161020212457_drop_editors.rb | 2 +- ...add_faculty_status_to_accounts_accounts.openstax_accounts.rb | 2 +- ...esforce_contact_id_to_accounts_accounts.openstax_accounts.rb | 2 +- ...ge_accounts_openstax_uid_to_be_nullable.openstax_accounts.rb | 2 +- ...change_accounts_username_to_be_nullable.openstax_accounts.rb | 2 +- ..._add_uuid_and_role_to_accounts_accounts.openstax_accounts.rb | 2 +- ...assign_missing_uuids_for_local_accounts.openstax_accounts.rb | 2 +- ...0171219215854_add_previous_refresh_token_to_access_tokens.rb | 2 +- ...support_identifier_to_accounts_accounts.openstax_accounts.rb | 2 +- ...002015_add_is_test_to_accounts_accounts.openstax_accounts.rb | 2 +- ...0180131161122_improve_publication_publication_group_index.rb | 2 +- ...161240_add_latest_published_version_to_publication_groups.rb | 2 +- db/migrate/20180220213530_add_nickname_to_publication_group.rb | 2 +- db/migrate/20180829201038_add_a15k_fields.rb | 2 +- db/migrate/20180927223921_add_confidential_to_applications.rb | 2 +- .../20180927223943_add_missing_doorkeeper_foreign_keys.rb | 2 +- db/migrate/20190308184133_add_implicit_signatures.fine_print.rb | 2 +- ...20_add_school_type_to_accounts_accounts.openstax_accounts.rb | 2 +- 83 files changed, 83 insertions(+), 83 deletions(-) diff --git a/db/migrate/20140724183731_create_doorkeeper_tables.rb b/db/migrate/20140724183731_create_doorkeeper_tables.rb index af5aa7d8..37ecbe7b 100644 --- a/db/migrate/20140724183731_create_doorkeeper_tables.rb +++ b/db/migrate/20140724183731_create_doorkeeper_tables.rb @@ -1,4 +1,4 @@ -class CreateDoorkeeperTables < ActiveRecord::Migration +class CreateDoorkeeperTables < ActiveRecord::Migration[4.2] def change create_table :oauth_applications do |t| t.string :name, null: false diff --git a/db/migrate/20140724183732_add_owner_to_application.rb b/db/migrate/20140724183732_add_owner_to_application.rb index fc85092e..e290472a 100644 --- a/db/migrate/20140724183732_add_owner_to_application.rb +++ b/db/migrate/20140724183732_add_owner_to_application.rb @@ -1,4 +1,4 @@ -class AddOwnerToApplication < ActiveRecord::Migration +class AddOwnerToApplication < ActiveRecord::Migration[4.2] def change add_column :oauth_applications, :owner_id, :integer add_column :oauth_applications, :owner_type, :string diff --git a/db/migrate/20140724183745_acts_as_votable_migration.rb b/db/migrate/20140724183745_acts_as_votable_migration.rb index 4bdcbe37..2516d700 100644 --- a/db/migrate/20140724183745_acts_as_votable_migration.rb +++ b/db/migrate/20140724183745_acts_as_votable_migration.rb @@ -1,4 +1,4 @@ -class ActsAsVotableMigration < ActiveRecord::Migration +class ActsAsVotableMigration < ActiveRecord::Migration[4.2] def self.up create_table :votes do |t| diff --git a/db/migrate/20140724183919_install_commontator.rb b/db/migrate/20140724183919_install_commontator.rb index 3b93792a..a4df0822 100644 --- a/db/migrate/20140724183919_install_commontator.rb +++ b/db/migrate/20140724183919_install_commontator.rb @@ -1,5 +1,5 @@ # This migration comes from commontator (originally 0) -class InstallCommontator < ActiveRecord::Migration +class InstallCommontator < ActiveRecord::Migration[4.2] def change create_table :commontator_comments do |t| t.string :creator_type diff --git a/db/migrate/20140724183932_install_fine_print.rb b/db/migrate/20140724183932_install_fine_print.rb index 5c3c5e27..0517ba68 100644 --- a/db/migrate/20140724183932_install_fine_print.rb +++ b/db/migrate/20140724183932_install_fine_print.rb @@ -1,5 +1,5 @@ # This migration comes from fine_print (originally 0) -class InstallFinePrint < ActiveRecord::Migration +class InstallFinePrint < ActiveRecord::Migration[4.2] def change create_table :fine_print_contracts do |t| t.string :name, :null => false diff --git a/db/migrate/20140724184012_create_openstax_accounts_accounts.rb b/db/migrate/20140724184012_create_openstax_accounts_accounts.rb index ccbd5ce8..540285e0 100644 --- a/db/migrate/20140724184012_create_openstax_accounts_accounts.rb +++ b/db/migrate/20140724184012_create_openstax_accounts_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 0) -class CreateOpenStaxAccountsAccounts < ActiveRecord::Migration +class CreateOpenStaxAccountsAccounts < ActiveRecord::Migration[4.2] def change create_table :openstax_accounts_accounts do |t| t.integer :openstax_uid, :null => false diff --git a/db/migrate/20140724184013_create_openstax_accounts_groups.openstax_accounts.rb b/db/migrate/20140724184013_create_openstax_accounts_groups.openstax_accounts.rb index 6f7deca2..629f1cee 100644 --- a/db/migrate/20140724184013_create_openstax_accounts_groups.openstax_accounts.rb +++ b/db/migrate/20140724184013_create_openstax_accounts_groups.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 1) -class CreateOpenStaxAccountsGroups < ActiveRecord::Migration +class CreateOpenStaxAccountsGroups < ActiveRecord::Migration[4.2] def change create_table :openstax_accounts_groups do |t| t.integer :openstax_uid, :null => false diff --git a/db/migrate/20140724184014_create_openstax_accounts_group_members.openstax_accounts.rb b/db/migrate/20140724184014_create_openstax_accounts_group_members.openstax_accounts.rb index e563986b..c55ad8eb 100644 --- a/db/migrate/20140724184014_create_openstax_accounts_group_members.openstax_accounts.rb +++ b/db/migrate/20140724184014_create_openstax_accounts_group_members.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 2) -class CreateOpenStaxAccountsGroupMembers < ActiveRecord::Migration +class CreateOpenStaxAccountsGroupMembers < ActiveRecord::Migration[4.2] def change create_table :openstax_accounts_group_members do |t| t.references :group, null: false diff --git a/db/migrate/20140724184015_create_openstax_accounts_group_owners.openstax_accounts.rb b/db/migrate/20140724184015_create_openstax_accounts_group_owners.openstax_accounts.rb index 6b47e522..66782e92 100644 --- a/db/migrate/20140724184015_create_openstax_accounts_group_owners.openstax_accounts.rb +++ b/db/migrate/20140724184015_create_openstax_accounts_group_owners.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 3) -class CreateOpenStaxAccountsGroupOwners < ActiveRecord::Migration +class CreateOpenStaxAccountsGroupOwners < ActiveRecord::Migration[4.2] def change create_table :openstax_accounts_group_owners do |t| t.references :group, null: false diff --git a/db/migrate/20140724184016_create_openstax_accounts_group_nestings.openstax_accounts.rb b/db/migrate/20140724184016_create_openstax_accounts_group_nestings.openstax_accounts.rb index bf8d4b1a..bf1b5f57 100644 --- a/db/migrate/20140724184016_create_openstax_accounts_group_nestings.openstax_accounts.rb +++ b/db/migrate/20140724184016_create_openstax_accounts_group_nestings.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 4) -class CreateOpenStaxAccountsGroupNestings < ActiveRecord::Migration +class CreateOpenStaxAccountsGroupNestings < ActiveRecord::Migration[4.2] def change create_table :openstax_accounts_group_nestings do |t| t.references :member_group, null: false diff --git a/db/migrate/20140724184630_create_users.rb b/db/migrate/20140724184630_create_users.rb index 22716422..efb35f7a 100644 --- a/db/migrate/20140724184630_create_users.rb +++ b/db/migrate/20140724184630_create_users.rb @@ -1,4 +1,4 @@ -class CreateUsers < ActiveRecord::Migration +class CreateUsers < ActiveRecord::Migration[4.2] def change create_table :users do |t| t.references :account, null: false diff --git a/db/migrate/20140724184800_create_administrators.rb b/db/migrate/20140724184800_create_administrators.rb index 00d5b5ea..e29a7e95 100644 --- a/db/migrate/20140724184800_create_administrators.rb +++ b/db/migrate/20140724184800_create_administrators.rb @@ -1,4 +1,4 @@ -class CreateAdministrators < ActiveRecord::Migration +class CreateAdministrators < ActiveRecord::Migration[4.2] def change create_table :administrators do |t| t.references :user, null: false diff --git a/db/migrate/20140724184944_create_exercises.rb b/db/migrate/20140724184944_create_exercises.rb index 932df6f6..c6050cc2 100644 --- a/db/migrate/20140724184944_create_exercises.rb +++ b/db/migrate/20140724184944_create_exercises.rb @@ -1,4 +1,4 @@ -class CreateExercises < ActiveRecord::Migration +class CreateExercises < ActiveRecord::Migration[4.2] def change create_table :exercises do |t| t.string :title diff --git a/db/migrate/20140724185123_create_questions.rb b/db/migrate/20140724185123_create_questions.rb index 86a85337..f2ccbad5 100644 --- a/db/migrate/20140724185123_create_questions.rb +++ b/db/migrate/20140724185123_create_questions.rb @@ -1,4 +1,4 @@ -class CreateQuestions < ActiveRecord::Migration +class CreateQuestions < ActiveRecord::Migration[4.2] def change create_table :questions do |t| t.references :exercise, null: false diff --git a/db/migrate/20140724185227_create_stems.rb b/db/migrate/20140724185227_create_stems.rb index 82140edb..787d774f 100644 --- a/db/migrate/20140724185227_create_stems.rb +++ b/db/migrate/20140724185227_create_stems.rb @@ -1,4 +1,4 @@ -class CreateStems < ActiveRecord::Migration +class CreateStems < ActiveRecord::Migration[4.2] def change create_table :stems do |t| t.references :question, null: false diff --git a/db/migrate/20140724203302_create_stylings.rb b/db/migrate/20140724203302_create_stylings.rb index a37ea973..05a09951 100644 --- a/db/migrate/20140724203302_create_stylings.rb +++ b/db/migrate/20140724203302_create_stylings.rb @@ -1,4 +1,4 @@ -class CreateStylings < ActiveRecord::Migration +class CreateStylings < ActiveRecord::Migration[4.2] def change create_table :stylings do |t| t.references :stylable, polymorphic: true, null: false diff --git a/db/migrate/20140724204932_create_answers.rb b/db/migrate/20140724204932_create_answers.rb index 939174f2..d6a0ea31 100644 --- a/db/migrate/20140724204932_create_answers.rb +++ b/db/migrate/20140724204932_create_answers.rb @@ -1,4 +1,4 @@ -class CreateAnswers < ActiveRecord::Migration +class CreateAnswers < ActiveRecord::Migration[4.2] def change create_table :answers do |t| t.references :question, null: false diff --git a/db/migrate/20140724211735_create_combo_choices.rb b/db/migrate/20140724211735_create_combo_choices.rb index 0f761de1..99508bc9 100644 --- a/db/migrate/20140724211735_create_combo_choices.rb +++ b/db/migrate/20140724211735_create_combo_choices.rb @@ -1,4 +1,4 @@ -class CreateComboChoices < ActiveRecord::Migration +class CreateComboChoices < ActiveRecord::Migration[4.2] def change create_table :combo_choices do |t| t.references :stem, null: false diff --git a/db/migrate/20140724211804_create_combo_choice_answers.rb b/db/migrate/20140724211804_create_combo_choice_answers.rb index 7e534880..e08f480c 100644 --- a/db/migrate/20140724211804_create_combo_choice_answers.rb +++ b/db/migrate/20140724211804_create_combo_choice_answers.rb @@ -1,4 +1,4 @@ -class CreateComboChoiceAnswers < ActiveRecord::Migration +class CreateComboChoiceAnswers < ActiveRecord::Migration[4.2] def change create_table :combo_choice_answers do |t| t.references :combo_choice, null: false diff --git a/db/migrate/20140728144750_create_solutions.rb b/db/migrate/20140728144750_create_solutions.rb index d1f37741..316f4c18 100644 --- a/db/migrate/20140728144750_create_solutions.rb +++ b/db/migrate/20140728144750_create_solutions.rb @@ -1,4 +1,4 @@ -class CreateSolutions < ActiveRecord::Migration +class CreateSolutions < ActiveRecord::Migration[4.2] def change create_table :solutions do |t| t.references :question, null: false diff --git a/db/migrate/20140728145131_create_derivations.rb b/db/migrate/20140728145131_create_derivations.rb index aa9abd56..09a01d64 100644 --- a/db/migrate/20140728145131_create_derivations.rb +++ b/db/migrate/20140728145131_create_derivations.rb @@ -1,4 +1,4 @@ -class CreateDerivations < ActiveRecord::Migration +class CreateDerivations < ActiveRecord::Migration[4.2] def change create_table :derivations do |t| t.sortable diff --git a/db/migrate/20140728145209_create_licenses.rb b/db/migrate/20140728145209_create_licenses.rb index 95c75ab4..a06efbd7 100644 --- a/db/migrate/20140728145209_create_licenses.rb +++ b/db/migrate/20140728145209_create_licenses.rb @@ -1,4 +1,4 @@ -class CreateLicenses < ActiveRecord::Migration +class CreateLicenses < ActiveRecord::Migration[4.2] def change create_table :licenses do |t| t.string :name, null: false diff --git a/db/migrate/20140728145518_create_question_dependencies.rb b/db/migrate/20140728145518_create_question_dependencies.rb index 04e35fb9..70aa2329 100644 --- a/db/migrate/20140728145518_create_question_dependencies.rb +++ b/db/migrate/20140728145518_create_question_dependencies.rb @@ -1,4 +1,4 @@ -class CreateQuestionDependencies < ActiveRecord::Migration +class CreateQuestionDependencies < ActiveRecord::Migration[4.2] def change create_table :question_dependencies do |t| t.references :parent_question, null: false diff --git a/db/migrate/20140728180028_create_lists.rb b/db/migrate/20140728180028_create_lists.rb index b88fed20..5ccdb62e 100644 --- a/db/migrate/20140728180028_create_lists.rb +++ b/db/migrate/20140728180028_create_lists.rb @@ -1,4 +1,4 @@ -class CreateLists < ActiveRecord::Migration +class CreateLists < ActiveRecord::Migration[4.2] def change create_table :lists do |t| t.string :name, null: false diff --git a/db/migrate/20140728191217_create_list_exercises.rb b/db/migrate/20140728191217_create_list_exercises.rb index 9451d1d4..58e82f5c 100644 --- a/db/migrate/20140728191217_create_list_exercises.rb +++ b/db/migrate/20140728191217_create_list_exercises.rb @@ -1,4 +1,4 @@ -class CreateListExercises < ActiveRecord::Migration +class CreateListExercises < ActiveRecord::Migration[4.2] def change create_table :list_exercises do |t| t.sortable diff --git a/db/migrate/20140728193853_create_attachments.rb b/db/migrate/20140728193853_create_attachments.rb index b0962d92..18d80ada 100644 --- a/db/migrate/20140728193853_create_attachments.rb +++ b/db/migrate/20140728193853_create_attachments.rb @@ -1,4 +1,4 @@ -class CreateAttachments < ActiveRecord::Migration +class CreateAttachments < ActiveRecord::Migration[4.2] def change create_table :attachments do |t| t.references :parent, polymorphic: true, null: false diff --git a/db/migrate/20140728222603_create_logics.rb b/db/migrate/20140728222603_create_logics.rb index 5a20010f..eea4613e 100644 --- a/db/migrate/20140728222603_create_logics.rb +++ b/db/migrate/20140728222603_create_logics.rb @@ -1,4 +1,4 @@ -class CreateLogics < ActiveRecord::Migration +class CreateLogics < ActiveRecord::Migration[4.2] def change create_table :logics do |t| t.references :parent, polymorphic: true, null: false diff --git a/db/migrate/20140728223106_create_logic_variables.rb b/db/migrate/20140728223106_create_logic_variables.rb index c9c04f41..28471eda 100644 --- a/db/migrate/20140728223106_create_logic_variables.rb +++ b/db/migrate/20140728223106_create_logic_variables.rb @@ -1,4 +1,4 @@ -class CreateLogicVariables < ActiveRecord::Migration +class CreateLogicVariables < ActiveRecord::Migration[4.2] def change create_table :logic_variables do |t| t.references :logic, null: false diff --git a/db/migrate/20140728223606_create_logic_variable_values.rb b/db/migrate/20140728223606_create_logic_variable_values.rb index 25626db6..cd1d78db 100644 --- a/db/migrate/20140728223606_create_logic_variable_values.rb +++ b/db/migrate/20140728223606_create_logic_variable_values.rb @@ -1,4 +1,4 @@ -class CreateLogicVariableValues < ActiveRecord::Migration +class CreateLogicVariableValues < ActiveRecord::Migration[4.2] def change create_table :logic_variable_values do |t| t.references :logic_variable, null: false diff --git a/db/migrate/20140819211115_create_deputizations.rb b/db/migrate/20140819211115_create_deputizations.rb index 261cb0cd..88e92e6d 100644 --- a/db/migrate/20140819211115_create_deputizations.rb +++ b/db/migrate/20140819211115_create_deputizations.rb @@ -1,4 +1,4 @@ -class CreateDeputizations < ActiveRecord::Migration +class CreateDeputizations < ActiveRecord::Migration[4.2] def change create_table :deputizations do |t| t.references :deputizer, null: false diff --git a/db/migrate/20140821185536_create_list_owners.rb b/db/migrate/20140821185536_create_list_owners.rb index f5d34a3c..b15da193 100644 --- a/db/migrate/20140821185536_create_list_owners.rb +++ b/db/migrate/20140821185536_create_list_owners.rb @@ -1,4 +1,4 @@ -class CreateListOwners < ActiveRecord::Migration +class CreateListOwners < ActiveRecord::Migration[4.2] def change create_table :list_owners do |t| t.references :owner, polymorphic: true, null: false diff --git a/db/migrate/20140821185603_create_list_editors.rb b/db/migrate/20140821185603_create_list_editors.rb index 541cf47b..4ddad004 100644 --- a/db/migrate/20140821185603_create_list_editors.rb +++ b/db/migrate/20140821185603_create_list_editors.rb @@ -1,4 +1,4 @@ -class CreateListEditors < ActiveRecord::Migration +class CreateListEditors < ActiveRecord::Migration[4.2] def change create_table :list_editors do |t| t.references :editor, polymorphic: true, null: false diff --git a/db/migrate/20140821185624_create_list_readers.rb b/db/migrate/20140821185624_create_list_readers.rb index a486348d..75c5d458 100644 --- a/db/migrate/20140821185624_create_list_readers.rb +++ b/db/migrate/20140821185624_create_list_readers.rb @@ -1,4 +1,4 @@ -class CreateListReaders < ActiveRecord::Migration +class CreateListReaders < ActiveRecord::Migration[4.2] def change create_table :list_readers do |t| t.references :reader, polymorphic: true, null: false diff --git a/db/migrate/20140822204013_create_publications.rb b/db/migrate/20140822204013_create_publications.rb index bd7792c2..942e0957 100644 --- a/db/migrate/20140822204013_create_publications.rb +++ b/db/migrate/20140822204013_create_publications.rb @@ -1,4 +1,4 @@ -class CreatePublications < ActiveRecord::Migration +class CreatePublications < ActiveRecord::Migration[4.2] def change create_table :publications do |t| t.references :publishable, polymorphic: true, null: false diff --git a/db/migrate/20140827193017_create_license_compatibilities.rb b/db/migrate/20140827193017_create_license_compatibilities.rb index 5ea26ca5..2204c624 100644 --- a/db/migrate/20140827193017_create_license_compatibilities.rb +++ b/db/migrate/20140827193017_create_license_compatibilities.rb @@ -1,4 +1,4 @@ -class CreateLicenseCompatibilities < ActiveRecord::Migration +class CreateLicenseCompatibilities < ActiveRecord::Migration[4.2] def change create_table :license_compatibilities do |t| t.references :original_license, null: false diff --git a/db/migrate/20140827221742_create_list_nestings.rb b/db/migrate/20140827221742_create_list_nestings.rb index 7e123491..dcce34a2 100644 --- a/db/migrate/20140827221742_create_list_nestings.rb +++ b/db/migrate/20140827221742_create_list_nestings.rb @@ -1,4 +1,4 @@ -class CreateListNestings < ActiveRecord::Migration +class CreateListNestings < ActiveRecord::Migration[4.2] def change create_table :list_nestings do |t| t.references :parent_list, null: false diff --git a/db/migrate/20140828151517_create_class_licenses.rb b/db/migrate/20140828151517_create_class_licenses.rb index 9d2792a4..84d5f6d1 100644 --- a/db/migrate/20140828151517_create_class_licenses.rb +++ b/db/migrate/20140828151517_create_class_licenses.rb @@ -1,4 +1,4 @@ -class CreateClassLicenses < ActiveRecord::Migration +class CreateClassLicenses < ActiveRecord::Migration[4.2] def change create_table :class_licenses do |t| t.sortable diff --git a/db/migrate/20140904205107_create_trusted_applications.rb b/db/migrate/20140904205107_create_trusted_applications.rb index 7db3f147..5ce3607f 100644 --- a/db/migrate/20140904205107_create_trusted_applications.rb +++ b/db/migrate/20140904205107_create_trusted_applications.rb @@ -1,4 +1,4 @@ -class CreateTrustedApplications < ActiveRecord::Migration +class CreateTrustedApplications < ActiveRecord::Migration[4.2] def change create_table :trusted_applications do |t| t.references :application, null: false diff --git a/db/migrate/20140916214330_create_editors.rb b/db/migrate/20140916214330_create_editors.rb index 594d2e9c..1ada023b 100644 --- a/db/migrate/20140916214330_create_editors.rb +++ b/db/migrate/20140916214330_create_editors.rb @@ -1,4 +1,4 @@ -class CreateEditors < ActiveRecord::Migration +class CreateEditors < ActiveRecord::Migration[4.2] def change create_table :editors do |t| t.sortable diff --git a/db/migrate/20140916214350_create_authors.rb b/db/migrate/20140916214350_create_authors.rb index 90d6d903..ef89cd01 100644 --- a/db/migrate/20140916214350_create_authors.rb +++ b/db/migrate/20140916214350_create_authors.rb @@ -1,4 +1,4 @@ -class CreateAuthors < ActiveRecord::Migration +class CreateAuthors < ActiveRecord::Migration[4.2] def change create_table :authors do |t| t.sortable diff --git a/db/migrate/20140916214406_create_copyright_holders.rb b/db/migrate/20140916214406_create_copyright_holders.rb index db9b0a02..cce05df1 100644 --- a/db/migrate/20140916214406_create_copyright_holders.rb +++ b/db/migrate/20140916214406_create_copyright_holders.rb @@ -1,4 +1,4 @@ -class CreateCopyrightHolders < ActiveRecord::Migration +class CreateCopyrightHolders < ActiveRecord::Migration[4.2] def change create_table :copyright_holders do |t| t.sortable diff --git a/db/migrate/20141107194147_create_stem_answers.rb b/db/migrate/20141107194147_create_stem_answers.rb index b645db07..05cd9564 100644 --- a/db/migrate/20141107194147_create_stem_answers.rb +++ b/db/migrate/20141107194147_create_stem_answers.rb @@ -1,4 +1,4 @@ -class CreateStemAnswers < ActiveRecord::Migration +class CreateStemAnswers < ActiveRecord::Migration[4.2] def change create_table :stem_answers do |t| t.references :stem, null: false diff --git a/db/migrate/20141118174146_create_hints.rb b/db/migrate/20141118174146_create_hints.rb index d62368ab..a1f81acb 100644 --- a/db/migrate/20141118174146_create_hints.rb +++ b/db/migrate/20141118174146_create_hints.rb @@ -1,4 +1,4 @@ -class CreateHints < ActiveRecord::Migration +class CreateHints < ActiveRecord::Migration[4.2] def change create_table :hints do |t| t.sortable diff --git a/db/migrate/20150225002223_create_tags.rb b/db/migrate/20150225002223_create_tags.rb index 336d30a4..ceab1921 100644 --- a/db/migrate/20150225002223_create_tags.rb +++ b/db/migrate/20150225002223_create_tags.rb @@ -1,4 +1,4 @@ -class CreateTags < ActiveRecord::Migration +class CreateTags < ActiveRecord::Migration[4.2] def change create_table :tags do |t| t.string :name, null: false diff --git a/db/migrate/20150225002247_create_exercise_tags.rb b/db/migrate/20150225002247_create_exercise_tags.rb index e854e9a8..470eaf63 100644 --- a/db/migrate/20150225002247_create_exercise_tags.rb +++ b/db/migrate/20150225002247_create_exercise_tags.rb @@ -1,4 +1,4 @@ -class CreateExerciseTags < ActiveRecord::Migration +class CreateExerciseTags < ActiveRecord::Migration[4.2] def change create_table :exercise_tags do |t| t.references :exercise, null: false diff --git a/db/migrate/20160212204251_add_sort_position_to_answers.rb b/db/migrate/20160212204251_add_sort_position_to_answers.rb index 1cc22140..e7998b8a 100644 --- a/db/migrate/20160212204251_add_sort_position_to_answers.rb +++ b/db/migrate/20160212204251_add_sort_position_to_answers.rb @@ -1,4 +1,4 @@ -class AddSortPositionToAnswers < ActiveRecord::Migration +class AddSortPositionToAnswers < ActiveRecord::Migration[4.2] def change add_sortable_column :answers, null: false add_sortable_index :answers, scope: :question_id diff --git a/db/migrate/20160212211016_add_answer_order_matters_to_questions.rb b/db/migrate/20160212211016_add_answer_order_matters_to_questions.rb index ee2a30f2..634cceda 100644 --- a/db/migrate/20160212211016_add_answer_order_matters_to_questions.rb +++ b/db/migrate/20160212211016_add_answer_order_matters_to_questions.rb @@ -1,4 +1,4 @@ -class AddAnswerOrderMattersToQuestions < ActiveRecord::Migration +class AddAnswerOrderMattersToQuestions < ActiveRecord::Migration[4.2] def change add_column :questions, :answer_order_matters, :boolean, null: false, default: true end diff --git a/db/migrate/20160226221827_rename_solutions_to_collaborator_solutions.rb b/db/migrate/20160226221827_rename_solutions_to_collaborator_solutions.rb index 88e0bea7..0a4d7583 100644 --- a/db/migrate/20160226221827_rename_solutions_to_collaborator_solutions.rb +++ b/db/migrate/20160226221827_rename_solutions_to_collaborator_solutions.rb @@ -1,4 +1,4 @@ -class RenameSolutionsToCollaboratorSolutions < ActiveRecord::Migration +class RenameSolutionsToCollaboratorSolutions < ActiveRecord::Migration[4.2] def change rename_table :solutions, :collaborator_solutions end diff --git a/db/migrate/20160226222403_create_community_solutions.rb b/db/migrate/20160226222403_create_community_solutions.rb index b39ed2ba..971acbc9 100644 --- a/db/migrate/20160226222403_create_community_solutions.rb +++ b/db/migrate/20160226222403_create_community_solutions.rb @@ -1,4 +1,4 @@ -class CreateCommunitySolutions < ActiveRecord::Migration +class CreateCommunitySolutions < ActiveRecord::Migration[4.2] def change create_table :community_solutions do |t| t.references :question, null: false diff --git a/db/migrate/20160406202802_add_sort_position_to_questions.rb b/db/migrate/20160406202802_add_sort_position_to_questions.rb index f4bac700..39b5d350 100644 --- a/db/migrate/20160406202802_add_sort_position_to_questions.rb +++ b/db/migrate/20160406202802_add_sort_position_to_questions.rb @@ -1,4 +1,4 @@ -class AddSortPositionToQuestions < ActiveRecord::Migration +class AddSortPositionToQuestions < ActiveRecord::Migration[4.2] def change add_sortable_column :questions, null: false add_sortable_index :questions, scope: :exercise_id diff --git a/db/migrate/20160413220455_create_vocab_terms.rb b/db/migrate/20160413220455_create_vocab_terms.rb index 56eadbdf..97bf32fe 100644 --- a/db/migrate/20160413220455_create_vocab_terms.rb +++ b/db/migrate/20160413220455_create_vocab_terms.rb @@ -1,4 +1,4 @@ -class CreateVocabTerms < ActiveRecord::Migration +class CreateVocabTerms < ActiveRecord::Migration[4.2] def change create_table :vocab_terms do |t| t.string :name, null: false diff --git a/db/migrate/20160413220518_create_vocab_distractors.rb b/db/migrate/20160413220518_create_vocab_distractors.rb index 572816da..d600d0f5 100644 --- a/db/migrate/20160413220518_create_vocab_distractors.rb +++ b/db/migrate/20160413220518_create_vocab_distractors.rb @@ -1,4 +1,4 @@ -class CreateVocabDistractors < ActiveRecord::Migration +class CreateVocabDistractors < ActiveRecord::Migration[4.2] def change create_table :vocab_distractors do |t| t.references :vocab_term, null: false diff --git a/db/migrate/20160413222116_remove_duplicate_indices.rb b/db/migrate/20160413222116_remove_duplicate_indices.rb index e01bc495..4cb37946 100644 --- a/db/migrate/20160413222116_remove_duplicate_indices.rb +++ b/db/migrate/20160413222116_remove_duplicate_indices.rb @@ -1,4 +1,4 @@ -class RemoveDuplicateIndices < ActiveRecord::Migration +class RemoveDuplicateIndices < ActiveRecord::Migration[4.2] def change remove_index :questions, :exercise_id remove_index :answers, :question_id diff --git a/db/migrate/20160413223442_add_vocab_term_id_to_exercises.rb b/db/migrate/20160413223442_add_vocab_term_id_to_exercises.rb index 2e06ecaf..95a935e4 100644 --- a/db/migrate/20160413223442_add_vocab_term_id_to_exercises.rb +++ b/db/migrate/20160413223442_add_vocab_term_id_to_exercises.rb @@ -1,4 +1,4 @@ -class AddVocabTermIdToExercises < ActiveRecord::Migration +class AddVocabTermIdToExercises < ActiveRecord::Migration[4.2] def change add_column :exercises, :vocab_term_id, :integer diff --git a/db/migrate/20160420172854_create_vocab_term_tags.rb b/db/migrate/20160420172854_create_vocab_term_tags.rb index 81c19d1e..840a5017 100644 --- a/db/migrate/20160420172854_create_vocab_term_tags.rb +++ b/db/migrate/20160420172854_create_vocab_term_tags.rb @@ -1,4 +1,4 @@ -class CreateVocabTermTags < ActiveRecord::Migration +class CreateVocabTermTags < ActiveRecord::Migration[4.2] def change create_table :vocab_term_tags do |t| t.references :vocab_term, foreign_key: { on_update: :cascade, on_delete: :cascade } diff --git a/db/migrate/20160423000618_change_questions_answer_order_matters_default_to_false.rb b/db/migrate/20160423000618_change_questions_answer_order_matters_default_to_false.rb index f5dc4e2d..3a79e0ea 100644 --- a/db/migrate/20160423000618_change_questions_answer_order_matters_default_to_false.rb +++ b/db/migrate/20160423000618_change_questions_answer_order_matters_default_to_false.rb @@ -1,4 +1,4 @@ -class ChangeQuestionsAnswerOrderMattersDefaultToFalse < ActiveRecord::Migration +class ChangeQuestionsAnswerOrderMattersDefaultToFalse < ActiveRecord::Migration[4.2] def change change_column_default :questions, :answer_order_matters, false end diff --git a/db/migrate/20160425191417_create_list_vocab_terms.rb b/db/migrate/20160425191417_create_list_vocab_terms.rb index bb5a2d6f..5f700af4 100644 --- a/db/migrate/20160425191417_create_list_vocab_terms.rb +++ b/db/migrate/20160425191417_create_list_vocab_terms.rb @@ -1,4 +1,4 @@ -class CreateListVocabTerms < ActiveRecord::Migration +class CreateListVocabTerms < ActiveRecord::Migration[4.2] def change create_table :list_vocab_terms do |t| t.sortable diff --git a/db/migrate/20160606214816_add_default_to_vocab_terms_definition.rb b/db/migrate/20160606214816_add_default_to_vocab_terms_definition.rb index b3c5078f..e4ad35c9 100644 --- a/db/migrate/20160606214816_add_default_to_vocab_terms_definition.rb +++ b/db/migrate/20160606214816_add_default_to_vocab_terms_definition.rb @@ -1,4 +1,4 @@ -class AddDefaultToVocabTermsDefinition < ActiveRecord::Migration +class AddDefaultToVocabTermsDefinition < ActiveRecord::Migration[4.2] def change change_column_default :vocab_terms, :definition, '' end diff --git a/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb b/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb index ecc2d5cc..9233a695 100644 --- a/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb +++ b/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb @@ -1,4 +1,4 @@ -class RemoveUuidFromCnxfeatureTags < ActiveRecord::Migration +class RemoveUuidFromCnxfeatureTags < ActiveRecord::Migration[4.2] def up Tag.where {name.like 'context-cnxfeature:%#%'}.update_all("name = regexp_replace(name, '^context-cnxfeature:[\\w-]+#([\\w-]+)$', 'context-cnxfeature:\\1')") end diff --git a/db/migrate/20160922220434_create_publication_groups.rb b/db/migrate/20160922220434_create_publication_groups.rb index 6bc2cfa3..8f38063b 100644 --- a/db/migrate/20160922220434_create_publication_groups.rb +++ b/db/migrate/20160922220434_create_publication_groups.rb @@ -1,4 +1,4 @@ -class CreatePublicationGroups < ActiveRecord::Migration +class CreatePublicationGroups < ActiveRecord::Migration[4.2] def change create_table :publication_groups do |t| t.string :publishable_type, null: false, index: true diff --git a/db/migrate/20160922231345_change_publications_number_to_publication_group_id.rb b/db/migrate/20160922231345_change_publications_number_to_publication_group_id.rb index 00340082..c414ac20 100644 --- a/db/migrate/20160922231345_change_publications_number_to_publication_group_id.rb +++ b/db/migrate/20160922231345_change_publications_number_to_publication_group_id.rb @@ -1,4 +1,4 @@ -class ChangePublicationsNumberToPublicationGroupId < ActiveRecord::Migration +class ChangePublicationsNumberToPublicationGroupId < ActiveRecord::Migration[4.2] def up add_column :publications, :publication_group_id, :integer diff --git a/db/migrate/20161006223624_add_uuid_to_publications.rb b/db/migrate/20161006223624_add_uuid_to_publications.rb index 299d514d..f631156e 100644 --- a/db/migrate/20161006223624_add_uuid_to_publications.rb +++ b/db/migrate/20161006223624_add_uuid_to_publications.rb @@ -1,4 +1,4 @@ -class AddUuidToPublications < ActiveRecord::Migration +class AddUuidToPublications < ActiveRecord::Migration[4.2] def change ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "pgcrypto";' diff --git a/db/migrate/20161019223527_create_list_publication_groups.rb b/db/migrate/20161019223527_create_list_publication_groups.rb index 147cf2f7..7784937d 100644 --- a/db/migrate/20161019223527_create_list_publication_groups.rb +++ b/db/migrate/20161019223527_create_list_publication_groups.rb @@ -1,4 +1,4 @@ -class CreateListPublicationGroups < ActiveRecord::Migration +class CreateListPublicationGroups < ActiveRecord::Migration[4.2] def change create_table :list_publication_groups do |t| t.sortable diff --git a/db/migrate/20161020001239_move_list_exercises_and_list_vocab_terms_to_list_publication_groups.rb b/db/migrate/20161020001239_move_list_exercises_and_list_vocab_terms_to_list_publication_groups.rb index 9364812f..b671b858 100644 --- a/db/migrate/20161020001239_move_list_exercises_and_list_vocab_terms_to_list_publication_groups.rb +++ b/db/migrate/20161020001239_move_list_exercises_and_list_vocab_terms_to_list_publication_groups.rb @@ -1,4 +1,4 @@ -class MoveListExercisesAndListVocabTermsToListPublicationGroups < ActiveRecord::Migration +class MoveListExercisesAndListVocabTermsToListPublicationGroups < ActiveRecord::Migration[4.2] def up exercise_id_list_id_pairs = \ ActiveRecord::Base.connection.execute('SELECT list_id, exercise_id FROM list_exercises;') diff --git a/db/migrate/20161020175420_rename_distractor_term_number_to_distractor_publication_group_id.rb b/db/migrate/20161020175420_rename_distractor_term_number_to_distractor_publication_group_id.rb index de1c0ad2..bfaea894 100644 --- a/db/migrate/20161020175420_rename_distractor_term_number_to_distractor_publication_group_id.rb +++ b/db/migrate/20161020175420_rename_distractor_term_number_to_distractor_publication_group_id.rb @@ -1,4 +1,4 @@ -class RenameDistractorTermNumberToDistractorPublicationGroupId < ActiveRecord::Migration +class RenameDistractorTermNumberToDistractorPublicationGroupId < ActiveRecord::Migration[4.2] def up add_column :vocab_distractors, :distractor_publication_group_id, :integer diff --git a/db/migrate/20161020212457_drop_editors.rb b/db/migrate/20161020212457_drop_editors.rb index e2666197..61feaae3 100644 --- a/db/migrate/20161020212457_drop_editors.rb +++ b/db/migrate/20161020212457_drop_editors.rb @@ -1,4 +1,4 @@ -class DropEditors < ActiveRecord::Migration +class DropEditors < ActiveRecord::Migration[4.2] def change drop_table :editors end diff --git a/db/migrate/20161024224932_add_faculty_status_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20161024224932_add_faculty_status_to_accounts_accounts.openstax_accounts.rb index 69f5218f..1b8fe542 100644 --- a/db/migrate/20161024224932_add_faculty_status_to_accounts_accounts.openstax_accounts.rb +++ b/db/migrate/20161024224932_add_faculty_status_to_accounts_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 5) -class AddFacultyStatusToAccountsAccounts < ActiveRecord::Migration +class AddFacultyStatusToAccountsAccounts < ActiveRecord::Migration[4.2] def change add_column :openstax_accounts_accounts, :faculty_status, :integer, default: 0, null: false add_index :openstax_accounts_accounts, :faculty_status diff --git a/db/migrate/20161024224933_add_salesforce_contact_id_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20161024224933_add_salesforce_contact_id_to_accounts_accounts.openstax_accounts.rb index ab66706d..9e9625fd 100644 --- a/db/migrate/20161024224933_add_salesforce_contact_id_to_accounts_accounts.openstax_accounts.rb +++ b/db/migrate/20161024224933_add_salesforce_contact_id_to_accounts_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 6) -class AddSalesforceContactIdToAccountsAccounts < ActiveRecord::Migration +class AddSalesforceContactIdToAccountsAccounts < ActiveRecord::Migration[4.2] def change add_column :openstax_accounts_accounts, :salesforce_contact_id, :string add_index :openstax_accounts_accounts, :salesforce_contact_id diff --git a/db/migrate/20171109183131_change_accounts_openstax_uid_to_be_nullable.openstax_accounts.rb b/db/migrate/20171109183131_change_accounts_openstax_uid_to_be_nullable.openstax_accounts.rb index 4b270888..94d9fb48 100644 --- a/db/migrate/20171109183131_change_accounts_openstax_uid_to_be_nullable.openstax_accounts.rb +++ b/db/migrate/20171109183131_change_accounts_openstax_uid_to_be_nullable.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 7) -class ChangeAccountsOpenStaxUidToBeNullable < ActiveRecord::Migration +class ChangeAccountsOpenStaxUidToBeNullable < ActiveRecord::Migration[4.2] def change change_column_null :openstax_accounts_accounts, :openstax_uid, true end diff --git a/db/migrate/20171109183132_change_accounts_username_to_be_nullable.openstax_accounts.rb b/db/migrate/20171109183132_change_accounts_username_to_be_nullable.openstax_accounts.rb index d85536cc..7ad48130 100644 --- a/db/migrate/20171109183132_change_accounts_username_to_be_nullable.openstax_accounts.rb +++ b/db/migrate/20171109183132_change_accounts_username_to_be_nullable.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 8) -class ChangeAccountsUsernameToBeNullable < ActiveRecord::Migration +class ChangeAccountsUsernameToBeNullable < ActiveRecord::Migration[4.2] def change change_column_null :openstax_accounts_accounts, :username, true end diff --git a/db/migrate/20171109183133_add_uuid_and_role_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20171109183133_add_uuid_and_role_to_accounts_accounts.openstax_accounts.rb index 54da92f2..82d3c694 100644 --- a/db/migrate/20171109183133_add_uuid_and_role_to_accounts_accounts.openstax_accounts.rb +++ b/db/migrate/20171109183133_add_uuid_and_role_to_accounts_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 9) -class AddUuidAndRoleToAccountsAccounts < ActiveRecord::Migration +class AddUuidAndRoleToAccountsAccounts < ActiveRecord::Migration[4.2] def change add_column :openstax_accounts_accounts, :uuid, :string add_index :openstax_accounts_accounts, :uuid, unique: true diff --git a/db/migrate/20171109210559_assign_missing_uuids_for_local_accounts.openstax_accounts.rb b/db/migrate/20171109210559_assign_missing_uuids_for_local_accounts.openstax_accounts.rb index 6a65f8c0..07878852 100644 --- a/db/migrate/20171109210559_assign_missing_uuids_for_local_accounts.openstax_accounts.rb +++ b/db/migrate/20171109210559_assign_missing_uuids_for_local_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 10) -class AssignMissingUuidsForLocalAccounts < ActiveRecord::Migration +class AssignMissingUuidsForLocalAccounts < ActiveRecord::Migration[4.2] def change enable_extension 'pgcrypto' diff --git a/db/migrate/20171219215854_add_previous_refresh_token_to_access_tokens.rb b/db/migrate/20171219215854_add_previous_refresh_token_to_access_tokens.rb index e3f07e35..263e3ff3 100644 --- a/db/migrate/20171219215854_add_previous_refresh_token_to_access_tokens.rb +++ b/db/migrate/20171219215854_add_previous_refresh_token_to_access_tokens.rb @@ -1,4 +1,4 @@ -class AddPreviousRefreshTokenToAccessTokens < ActiveRecord::Migration +class AddPreviousRefreshTokenToAccessTokens < ActiveRecord::Migration[4.2] def change add_column( :oauth_access_tokens, diff --git a/db/migrate/20171220232359_add_support_identifier_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20171220232359_add_support_identifier_to_accounts_accounts.openstax_accounts.rb index fec75d43..ada20ba0 100644 --- a/db/migrate/20171220232359_add_support_identifier_to_accounts_accounts.openstax_accounts.rb +++ b/db/migrate/20171220232359_add_support_identifier_to_accounts_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 11) -class AddSupportIdentifierToAccountsAccounts < ActiveRecord::Migration +class AddSupportIdentifierToAccountsAccounts < ActiveRecord::Migration[4.2] def change enable_extension :citext diff --git a/db/migrate/20171222002015_add_is_test_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20171222002015_add_is_test_to_accounts_accounts.openstax_accounts.rb index 4d4b3b73..e592ca13 100644 --- a/db/migrate/20171222002015_add_is_test_to_accounts_accounts.openstax_accounts.rb +++ b/db/migrate/20171222002015_add_is_test_to_accounts_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 12) -class AddIsTestToAccountsAccounts < ActiveRecord::Migration +class AddIsTestToAccountsAccounts < ActiveRecord::Migration[4.2] def change add_column :openstax_accounts_accounts, :is_test, :boolean end diff --git a/db/migrate/20180131161122_improve_publication_publication_group_index.rb b/db/migrate/20180131161122_improve_publication_publication_group_index.rb index 916328d6..2b332d19 100644 --- a/db/migrate/20180131161122_improve_publication_publication_group_index.rb +++ b/db/migrate/20180131161122_improve_publication_publication_group_index.rb @@ -1,4 +1,4 @@ -class ImprovePublicationPublicationGroupIndex < ActiveRecord::Migration +class ImprovePublicationPublicationGroupIndex < ActiveRecord::Migration[4.2] def change remove_index :publications, :publication_group_id diff --git a/db/migrate/20180131161240_add_latest_published_version_to_publication_groups.rb b/db/migrate/20180131161240_add_latest_published_version_to_publication_groups.rb index 3496cfb9..f1575ba0 100644 --- a/db/migrate/20180131161240_add_latest_published_version_to_publication_groups.rb +++ b/db/migrate/20180131161240_add_latest_published_version_to_publication_groups.rb @@ -1,4 +1,4 @@ -class AddLatestPublishedVersionToPublicationGroups < ActiveRecord::Migration +class AddLatestPublishedVersionToPublicationGroups < ActiveRecord::Migration[4.2] def change add_column :publication_groups, :latest_version, :integer add_column :publication_groups, :latest_published_version, :integer diff --git a/db/migrate/20180220213530_add_nickname_to_publication_group.rb b/db/migrate/20180220213530_add_nickname_to_publication_group.rb index aa477e6b..c151cbb2 100644 --- a/db/migrate/20180220213530_add_nickname_to_publication_group.rb +++ b/db/migrate/20180220213530_add_nickname_to_publication_group.rb @@ -1,4 +1,4 @@ -class AddNicknameToPublicationGroup < ActiveRecord::Migration +class AddNicknameToPublicationGroup < ActiveRecord::Migration[4.2] def change add_column :publication_groups, :nickname, :string add_index :publication_groups, :nickname, unique: true diff --git a/db/migrate/20180829201038_add_a15k_fields.rb b/db/migrate/20180829201038_add_a15k_fields.rb index 489ee122..1dff759c 100644 --- a/db/migrate/20180829201038_add_a15k_fields.rb +++ b/db/migrate/20180829201038_add_a15k_fields.rb @@ -1,4 +1,4 @@ -class AddA15kFields < ActiveRecord::Migration +class AddA15kFields < ActiveRecord::Migration[4.2] def change add_column :exercises, :a15k_identifier, :string, index: true add_column :exercises, :a15k_version, :integer diff --git a/db/migrate/20180927223921_add_confidential_to_applications.rb b/db/migrate/20180927223921_add_confidential_to_applications.rb index 5e01a963..06d66fd6 100644 --- a/db/migrate/20180927223921_add_confidential_to_applications.rb +++ b/db/migrate/20180927223921_add_confidential_to_applications.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class AddConfidentialToApplications < ActiveRecord::Migration +class AddConfidentialToApplications < ActiveRecord::Migration[4.2] def change add_column( :oauth_applications, diff --git a/db/migrate/20180927223943_add_missing_doorkeeper_foreign_keys.rb b/db/migrate/20180927223943_add_missing_doorkeeper_foreign_keys.rb index 8340ffde..f13466db 100644 --- a/db/migrate/20180927223943_add_missing_doorkeeper_foreign_keys.rb +++ b/db/migrate/20180927223943_add_missing_doorkeeper_foreign_keys.rb @@ -1,4 +1,4 @@ -class AddMissingDoorkeeperForeignKeys < ActiveRecord::Migration +class AddMissingDoorkeeperForeignKeys < ActiveRecord::Migration[4.2] def change add_foreign_key( :oauth_access_grants, diff --git a/db/migrate/20190308184133_add_implicit_signatures.fine_print.rb b/db/migrate/20190308184133_add_implicit_signatures.fine_print.rb index 0ed326fc..39d32837 100644 --- a/db/migrate/20190308184133_add_implicit_signatures.fine_print.rb +++ b/db/migrate/20190308184133_add_implicit_signatures.fine_print.rb @@ -1,5 +1,5 @@ # This migration comes from fine_print (originally 1) -class AddImplicitSignatures < ActiveRecord::Migration +class AddImplicitSignatures < ActiveRecord::Migration[4.2] def change add_column :fine_print_signatures, :is_implicit, :boolean, null: false, default: false diff --git a/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb index 1c042203..6d855405 100644 --- a/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb +++ b/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 13) -class AddSchoolTypeToAccountsAccounts < ActiveRecord::Migration[4.2] +class AddSchoolTypeToAccountsAccounts < ActiveRecord::Migration[4.2][4.2] def change add_column :openstax_accounts_accounts, :school_type, :integer, null: false, default: 0 add_index :openstax_accounts_accounts, :school_type From 42b3cf36f6046441b4abd73697c325e5af59d157 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Wed, 5 Jun 2019 15:19:22 -0500 Subject: [PATCH 32/50] method_alias_chain deprecation (minimal fix) --- config/initializers/kramdown.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config/initializers/kramdown.rb b/config/initializers/kramdown.rb index 27bb7383..b6d06c00 100644 --- a/config/initializers/kramdown.rb +++ b/config/initializers/kramdown.rb @@ -12,7 +12,8 @@ def add_link_with_attachments(el, href, title, alt_text = nil, ial = nil) add_link_without_attachments(el, href, title, alt_text, ial) end - alias_method_chain :add_link, :attachments + alias_method :add_link_without_attachments, :add_link + alias_method :add_link, :add_link_with_attachments SINGLE_DOLLAR_INLINE_MATH_START = /(? Date: Wed, 5 Jun 2019 17:44:28 -0500 Subject: [PATCH 33/50] belongs_to default required --- app/models/administrator.rb | 2 +- app/models/answer.rb | 1 - app/models/attachment.rb | 1 - app/models/author.rb | 3 +-- app/models/class_license.rb | 1 - app/models/combo_choice.rb | 1 - app/models/combo_choice_answer.rb | 3 +-- app/models/copyright_holder.rb | 3 +-- app/models/deputization.rb | 4 +--- app/models/derivation.rb | 3 +-- app/models/exercise.rb | 2 +- app/models/exercise_tag.rb | 3 +-- app/models/hint.rb | 1 - app/models/license_compatibility.rb | 3 +-- app/models/list_editor.rb | 3 +-- app/models/list_nesting.rb | 3 +-- app/models/list_owner.rb | 3 +-- app/models/list_publication_group.rb | 3 +-- app/models/list_reader.rb | 3 +-- app/models/logic.rb | 1 - app/models/logic_variable.rb | 1 - app/models/logic_variable_value.rb | 1 - app/models/publication.rb | 3 +-- app/models/question.rb | 2 -- app/models/question_dependency.rb | 4 +--- app/models/stem.rb | 1 - app/models/stem_answer.rb | 3 +-- app/models/styling.rb | 1 - app/models/trusted_application.rb | 2 +- app/models/user.rb | 2 +- app/models/vocab_distractor.rb | 3 +-- app/models/vocab_term_tag.rb | 3 +-- config/application.rb | 4 ++++ config/initializers/new_framework_defaults.rb | 8 ++++---- spec/models/administrator_spec.rb | 2 -- spec/models/answer_spec.rb | 1 - spec/models/attachment_spec.rb | 2 -- spec/models/author_spec.rb | 3 --- spec/models/class_license_spec.rb | 1 - spec/models/combo_choice_answer_spec.rb | 3 --- spec/models/combo_choice_spec.rb | 1 - spec/models/copyright_holder_spec.rb | 3 --- spec/models/deputization_spec.rb | 3 --- spec/models/derivation_spec.rb | 4 +--- spec/models/exercise_tag_spec.rb | 3 --- spec/models/hint_spec.rb | 1 - spec/models/license_compatibility_spec.rb | 3 --- spec/models/list_editor_spec.rb | 3 --- spec/models/list_nesting_spec.rb | 3 --- spec/models/list_owner_spec.rb | 3 --- spec/models/list_publication_group_spec.rb | 3 --- spec/models/list_reader_spec.rb | 3 --- spec/models/logic_spec.rb | 1 - spec/models/logic_variable_spec.rb | 1 - spec/models/logic_variable_value_spec.rb | 1 - spec/models/publication_spec.rb | 5 +---- spec/models/question_dependency_spec.rb | 3 --- spec/models/question_spec.rb | 2 +- spec/models/stem_answer_spec.rb | 2 -- spec/models/stem_spec.rb | 1 - spec/models/styling_spec.rb | 1 - spec/models/trusted_application_spec.rb | 2 -- spec/models/user_spec.rb | 2 -- spec/models/vocab_distractor_spec.rb | 3 +-- spec/models/vocab_term_tag_spec.rb | 3 --- 65 files changed, 33 insertions(+), 124 deletions(-) diff --git a/app/models/administrator.rb b/app/models/administrator.rb index 89d2f256..85cc0f73 100644 --- a/app/models/administrator.rb +++ b/app/models/administrator.rb @@ -2,6 +2,6 @@ class Administrator < ApplicationRecord belongs_to :user - validates :user, presence: true, uniqueness: true + validates :user, uniqueness: true end diff --git a/app/models/answer.rb b/app/models/answer.rb index a16e850e..8201884b 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -10,7 +10,6 @@ class Answer < ApplicationRecord has_many :combo_choice_answers, dependent: :destroy - validates :question, presence: true validates :content, presence: true end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 9cea9089..d2540ff1 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -7,7 +7,6 @@ class Attachment < ApplicationRecord before_update { raise ActiveRecord::ReadOnlyRecord } # Prevent updates validates :asset, presence: true - validates :parent, presence: true validate :unique_asset def filename diff --git a/app/models/author.rb b/app/models/author.rb index 07340599..a2ef81c9 100644 --- a/app/models/author.rb +++ b/app/models/author.rb @@ -4,8 +4,7 @@ class Author < ApplicationRecord belongs_to :user - validates :publication, presence: true - validates :user, presence: true, uniqueness: { scope: :publication_id } + validates :user, uniqueness: { scope: :publication_id } delegate :name, to: :user diff --git a/app/models/class_license.rb b/app/models/class_license.rb index 67a3ca3d..9467d771 100644 --- a/app/models/class_license.rb +++ b/app/models/class_license.rb @@ -7,7 +7,6 @@ class ClassLicense < ApplicationRecord has_many :same_class, class_name: 'ClassLicense', foreign_key: :class_name, primary_key: :class_name - validates :license, presence: true validates :class_name, presence: true, uniqueness: { scope: :license_id } end diff --git a/app/models/combo_choice.rb b/app/models/combo_choice.rb index 8553b456..cbf6811c 100644 --- a/app/models/combo_choice.rb +++ b/app/models/combo_choice.rb @@ -4,7 +4,6 @@ class ComboChoice < ApplicationRecord has_many :combo_choice_answers, dependent: :destroy - validates :stem, presence: true validates :correctness, presence: true, numericality: { greater_than_or_equal_to: 0.0, less_than_or_equal_to: 1.0 } diff --git a/app/models/combo_choice_answer.rb b/app/models/combo_choice_answer.rb index cb0d1f1d..091354ae 100644 --- a/app/models/combo_choice_answer.rb +++ b/app/models/combo_choice_answer.rb @@ -3,8 +3,7 @@ class ComboChoiceAnswer < ApplicationRecord belongs_to :combo_choice belongs_to :answer - validates :combo_choice, presence: true - validates :answer, presence: true, uniqueness: { scope: :combo_choice_id } + validates :answer, uniqueness: { scope: :combo_choice_id } validate :same_question protected diff --git a/app/models/copyright_holder.rb b/app/models/copyright_holder.rb index fe99e368..4027d4e4 100644 --- a/app/models/copyright_holder.rb +++ b/app/models/copyright_holder.rb @@ -4,8 +4,7 @@ class CopyrightHolder < ApplicationRecord belongs_to :user - validates :publication, presence: true - validates :user, presence: true, uniqueness: { scope: :publication_id } + validates :user, uniqueness: { scope: :publication_id } delegate :name, to: :user diff --git a/app/models/deputization.rb b/app/models/deputization.rb index 1d444f33..de1cf05c 100644 --- a/app/models/deputization.rb +++ b/app/models/deputization.rb @@ -3,8 +3,6 @@ class Deputization < ApplicationRecord belongs_to :deputizer, class_name: 'User', inverse_of: :child_deputizations belongs_to :deputy, polymorphic: true - validates :deputy, presence: true - validates :deputizer, presence: true, - uniqueness: { scope: [:deputy_type, :deputy_id] } + validates :deputizer, uniqueness: { scope: [:deputy_type, :deputy_id] } end diff --git a/app/models/derivation.rb b/app/models/derivation.rb index fb2b2241..8597cbb2 100644 --- a/app/models/derivation.rb +++ b/app/models/derivation.rb @@ -1,9 +1,8 @@ class Derivation < ApplicationRecord sortable_belongs_to :derived_publication, class_name: 'Publication', inverse_of: :sources - belongs_to :source_publication, class_name: 'Publication', inverse_of: :derivations + belongs_to :source_publication, class_name: 'Publication', inverse_of: :derivations, optional: true - validates :derived_publication, presence: true validates :source_publication, uniqueness: { scope: :derived_publication_id, allow_nil: true } validate :different_publications, :source_or_custom diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 2710197e..d7856889 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -87,7 +87,7 @@ class Exercise < ApplicationRecord sortable_has_many :questions, dependent: :destroy, autosave: true, inverse_of: :exercise - belongs_to :vocab_term, touch: true + belongs_to :vocab_term, touch: true, optional: true scope :can_release_to_a15k, -> { where(release_to_a15k: true) } scope :not_released_to_a15k, -> { where(a15k_identifier: nil) } diff --git a/app/models/exercise_tag.rb b/app/models/exercise_tag.rb index 095b985e..d284542f 100644 --- a/app/models/exercise_tag.rb +++ b/app/models/exercise_tag.rb @@ -2,6 +2,5 @@ class ExerciseTag < ApplicationRecord belongs_to :exercise belongs_to :tag - validates :exercise, presence: true - validates :tag, presence: true, uniqueness: { scope: :exercise_id } + validates :tag, uniqueness: { scope: :exercise_id } end diff --git a/app/models/hint.rb b/app/models/hint.rb index 662e5fa8..c1e6bee7 100644 --- a/app/models/hint.rb +++ b/app/models/hint.rb @@ -2,7 +2,6 @@ class Hint < ApplicationRecord sortable_belongs_to :question, inverse_of: :hints - validates :question, presence: true validates :content, presence: true end diff --git a/app/models/license_compatibility.rb b/app/models/license_compatibility.rb index 7dd98620..9c9b6db9 100644 --- a/app/models/license_compatibility.rb +++ b/app/models/license_compatibility.rb @@ -5,7 +5,6 @@ class LicenseCompatibility < ApplicationRecord belongs_to :combined_license, class_name: 'License', inverse_of: :original_license_compatibilities - validates :original_license, presence: true - validates :combined_license, presence: true, uniqueness: { scope: :original_license_id } + validates :combined_license, uniqueness: { scope: :original_license_id } end diff --git a/app/models/list_editor.rb b/app/models/list_editor.rb index 279f1933..d2e356b1 100644 --- a/app/models/list_editor.rb +++ b/app/models/list_editor.rb @@ -3,7 +3,6 @@ class ListEditor < ApplicationRecord belongs_to :list, inverse_of: :list_editors belongs_to :editor, polymorphic: true - validates :list, presence: true, uniqueness: { scope: [:editor_type, :editor_id] } - validates :editor, presence: true + validates :list, uniqueness: { scope: [:editor_type, :editor_id] } end diff --git a/app/models/list_nesting.rb b/app/models/list_nesting.rb index 240d12a4..ffb153a0 100644 --- a/app/models/list_nesting.rb +++ b/app/models/list_nesting.rb @@ -3,7 +3,6 @@ class ListNesting < ApplicationRecord belongs_to :parent_list, class_name: 'List', inverse_of: :child_list_nestings belongs_to :child_list, class_name: 'List', inverse_of: :parent_list_nesting - validates :parent_list, presence: true - validates :child_list, presence: true, uniqueness: true + validates :child_list, uniqueness: true end diff --git a/app/models/list_owner.rb b/app/models/list_owner.rb index 85ee0657..9bea0f80 100644 --- a/app/models/list_owner.rb +++ b/app/models/list_owner.rb @@ -3,7 +3,6 @@ class ListOwner < ApplicationRecord belongs_to :list, inverse_of: :list_owners belongs_to :owner, polymorphic: true - validates :list, presence: true, uniqueness: { scope: [:owner_type, :owner_id] } - validates :owner, presence: true + validates :list, uniqueness: { scope: [:owner_type, :owner_id] } end diff --git a/app/models/list_publication_group.rb b/app/models/list_publication_group.rb index c8d418f7..4a788bb4 100644 --- a/app/models/list_publication_group.rb +++ b/app/models/list_publication_group.rb @@ -3,7 +3,6 @@ class ListPublicationGroup < ApplicationRecord sortable_belongs_to :list, inverse_of: :list_publication_groups belongs_to :publication_group, inverse_of: :list_publication_groups - validates :list, presence: true - validates :publication_group, presence: true, uniqueness: { scope: :list_id } + validates :publication_group, uniqueness: { scope: :list_id } end diff --git a/app/models/list_reader.rb b/app/models/list_reader.rb index 283fc1e7..bfb5b0d3 100644 --- a/app/models/list_reader.rb +++ b/app/models/list_reader.rb @@ -3,7 +3,6 @@ class ListReader < ApplicationRecord belongs_to :list, inverse_of: :list_readers belongs_to :reader, polymorphic: true - validates :list, presence: true, uniqueness: { scope: [:reader_type, :reader_id] } - validates :reader, presence: true + validates :list, uniqueness: { scope: [:reader_type, :reader_id] } end diff --git a/app/models/logic.rb b/app/models/logic.rb index ca62cc7b..8763d53f 100644 --- a/app/models/logic.rb +++ b/app/models/logic.rb @@ -4,7 +4,6 @@ class Logic < ApplicationRecord has_many :logic_variables, dependent: :destroy - validates :parent, presence: true validates :parent_id, uniqueness: { scope: :parent_type } validates :language, presence: true, inclusion: { in: Language.all } validates :code, presence: true diff --git a/app/models/logic_variable.rb b/app/models/logic_variable.rb index a219dc58..181306fc 100644 --- a/app/models/logic_variable.rb +++ b/app/models/logic_variable.rb @@ -14,7 +14,6 @@ class LogicVariable < ApplicationRecord has_many :logic_variable_values, dependent: :destroy - validates :logic, presence: true validates :variable, presence: true, uniqueness: { scope: :logic_id }, format: { with: VARIABLE_REGEX }, exclusion: { in: RESERVED_WORDS } diff --git a/app/models/logic_variable_value.rb b/app/models/logic_variable_value.rb index 88b56716..52856cfc 100644 --- a/app/models/logic_variable_value.rb +++ b/app/models/logic_variable_value.rb @@ -2,7 +2,6 @@ class LogicVariableValue < ApplicationRecord belongs_to :logic_variable - validates :logic_variable, presence: true validates :seed, presence: true, uniqueness: { scope: :logic_variable_id } validates :value, presence: true diff --git a/app/models/publication.rb b/app/models/publication.rb index 75561fcc..d72ac7da 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -2,7 +2,7 @@ class Publication < ApplicationRecord belongs_to :publication_group, inverse_of: :publications belongs_to :publishable, polymorphic: true, inverse_of: :publication, touch: true - belongs_to :license + belongs_to :license, optional: true sortable_has_many :authors, dependent: :destroy, inverse_of: :publication sortable_has_many :copyright_holders, dependent: :destroy, inverse_of: :publication @@ -17,7 +17,6 @@ class Publication < ApplicationRecord delegate :group_uuid, :number, :nickname, :nickname=, to: :publication_group - validates :publication_group, :publishable, presence: true validates :publishable_id, uniqueness: { scope: :publishable_type } validates :uuid, presence: true, uniqueness: true validates :version, presence: true, uniqueness: { scope: :publication_group_id }, diff --git a/app/models/question.rb b/app/models/question.rb index 52b9164d..c0845960 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -23,6 +23,4 @@ class Question < ApplicationRecord foreign_key: :parent_question_id, dependent: :destroy, inverse_of: :parent_question - validates :exercise, presence: true - end diff --git a/app/models/question_dependency.rb b/app/models/question_dependency.rb index 4fc260b9..7755176f 100644 --- a/app/models/question_dependency.rb +++ b/app/models/question_dependency.rb @@ -5,9 +5,7 @@ class QuestionDependency < ApplicationRecord belongs_to :dependent_question, class_name: 'Question', inverse_of: :parent_dependencies - validates :parent_question, presence: true - validates :dependent_question, presence: true, - uniqueness: { scope: :parent_question_id } + validates :dependent_question, uniqueness: { scope: :parent_question_id } validate :same_exercise diff --git a/app/models/stem.rb b/app/models/stem.rb index 227784e6..722eec8c 100644 --- a/app/models/stem.rb +++ b/app/models/stem.rb @@ -12,7 +12,6 @@ class Stem < ApplicationRecord has_many :combo_choices, dependent: :destroy validates :stylings, presence: true - validates :question, presence: true validates :content, presence: true end diff --git a/app/models/stem_answer.rb b/app/models/stem_answer.rb index b7216bb3..bcf0e5f9 100644 --- a/app/models/stem_answer.rb +++ b/app/models/stem_answer.rb @@ -3,8 +3,7 @@ class StemAnswer < ApplicationRecord belongs_to :stem belongs_to :answer - validates :stem, presence: true - validates :answer, presence: true, uniqueness: { scope: :stem_id } + validates :answer, uniqueness: { scope: :stem_id } validates :correctness, presence: true, numericality: { greater_than_or_equal_to: 0.0, less_than_or_equal_to: 1.0 } diff --git a/app/models/styling.rb b/app/models/styling.rb index 250208e2..3a3dae1c 100644 --- a/app/models/styling.rb +++ b/app/models/styling.rb @@ -2,7 +2,6 @@ class Styling < ApplicationRecord belongs_to :stylable, polymorphic: true, inverse_of: :stylings - validates :stylable, presence: true validates :style, presence: true, inclusion: { in: Style.all }, uniqueness: { scope: [:stylable_type, :stylable_id] } diff --git a/app/models/trusted_application.rb b/app/models/trusted_application.rb index 1825aeb2..6c3a1085 100644 --- a/app/models/trusted_application.rb +++ b/app/models/trusted_application.rb @@ -3,6 +3,6 @@ class TrustedApplication < ApplicationRecord belongs_to :application, class_name: 'Doorkeeper::Application', inverse_of: :trusted_application - validates :application, presence: true, uniqueness: true + validates :application, uniqueness: true end diff --git a/app/models/user.rb b/app/models/user.rb index 8572d945..b7406c6a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -33,7 +33,7 @@ class User < ApplicationRecord has_many :sortings, dependent: :destroy - validates :account, presence: true, uniqueness: true + validates :account, uniqueness: true delegate :username, :first_name, :last_name, :full_name, :title, :name, :casual_name, :first_name=, :last_name=, :full_name=, diff --git a/app/models/vocab_distractor.rb b/app/models/vocab_distractor.rb index 4b03723c..4a6cb696 100644 --- a/app/models/vocab_distractor.rb +++ b/app/models/vocab_distractor.rb @@ -3,8 +3,7 @@ class VocabDistractor < ApplicationRecord belongs_to :distractor_publication_group, class_name: 'PublicationGroup', inverse_of: :vocab_distractors - validates :vocab_term, presence: true - validates :distractor_publication_group, presence: true, uniqueness: { scope: :vocab_term_id } + validates :distractor_publication_group, uniqueness: { scope: :vocab_term_id } validates :distractor_term, presence: true validate :vocab_term_publication_group, :different_terms diff --git a/app/models/vocab_term_tag.rb b/app/models/vocab_term_tag.rb index 54e959b1..b0071f47 100644 --- a/app/models/vocab_term_tag.rb +++ b/app/models/vocab_term_tag.rb @@ -2,6 +2,5 @@ class VocabTermTag < ApplicationRecord belongs_to :vocab_term belongs_to :tag - validates :vocab_term, presence: true - validates :tag, presence: true, uniqueness: { scope: :vocab_term_id } + validates :tag, uniqueness: { scope: :vocab_term_id } end diff --git a/config/application.rb b/config/application.rb index 839526cc..5315560b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,5 +35,9 @@ class Application < Rails::Application compress: true, compress_threshold: 1.kilobyte } + end end + +# Require `belongs_to` associations by default. Previous versions had false. +Rails.application.config.active_record.belongs_to_required_by_default = true diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb index fea40a14..9663f82e 100644 --- a/config/initializers/new_framework_defaults.rb +++ b/config/initializers/new_framework_defaults.rb @@ -6,17 +6,17 @@ # # Read the Guide for Upgrading Ruby on Rails for more info on each option. -Rails.application.config.action_controller.raise_on_unfiltered_parameters = true +Rails.application.config.action_controller.raise_on_unfiltered_parameters = false # Enable per-form CSRF tokens. Previous versions had false. -Rails.application.config.action_controller.per_form_csrf_tokens = false +Rails.application.config.action_controller.per_form_csrf_tokens = true # Enable origin-checking CSRF mitigation. Previous versions had false. -Rails.application.config.action_controller.forgery_protection_origin_check = false +Rails.application.config.action_controller.forgery_protection_origin_check = true # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. # Previous versions had false. -ActiveSupport.to_time_preserves_timezone = false +ActiveSupport.to_time_preserves_timezone = true # Require `belongs_to` associations by default. Previous versions had false. Rails.application.config.active_record.belongs_to_required_by_default = true diff --git a/spec/models/administrator_spec.rb b/spec/models/administrator_spec.rb index a80b1e50..9882ca3a 100644 --- a/spec/models/administrator_spec.rb +++ b/spec/models/administrator_spec.rb @@ -6,8 +6,6 @@ it { is_expected.to belong_to(:user) } - it { is_expected.to validate_presence_of(:user) } - it { is_expected.to validate_uniqueness_of(:user) } end diff --git a/spec/models/answer_spec.rb b/spec/models/answer_spec.rb index bcd19753..12a960b2 100644 --- a/spec/models/answer_spec.rb +++ b/spec/models/answer_spec.rb @@ -6,7 +6,6 @@ it { is_expected.to have_many(:combo_choice_answers).dependent(:destroy) } - it { is_expected.to validate_presence_of(:question) } it { is_expected.to validate_presence_of(:content) } end diff --git a/spec/models/attachment_spec.rb b/spec/models/attachment_spec.rb index bcaa9442..10ee5924 100644 --- a/spec/models/attachment_spec.rb +++ b/spec/models/attachment_spec.rb @@ -9,8 +9,6 @@ it { is_expected.to belong_to(:parent) } - it { is_expected.to validate_presence_of(:parent) } - it 'requires a unique asset for each parent' do attachment_2 = FactoryBot.build :attachment, parent: attachment.parent, asset: nil expect(attachment_2).not_to be_valid diff --git a/spec/models/author_spec.rb b/spec/models/author_spec.rb index 76a7cd7d..b4b9cb75 100644 --- a/spec/models/author_spec.rb +++ b/spec/models/author_spec.rb @@ -7,9 +7,6 @@ it { is_expected.to belong_to(:publication) } it { is_expected.to belong_to(:user) } - it { is_expected.to validate_presence_of(:publication) } - it { is_expected.to validate_presence_of(:user) } - it { is_expected.to delegate_method(:name).to(:user) } it 'requires a unique user for each publication' do diff --git a/spec/models/class_license_spec.rb b/spec/models/class_license_spec.rb index 800874c7..a94d4aa0 100644 --- a/spec/models/class_license_spec.rb +++ b/spec/models/class_license_spec.rb @@ -6,7 +6,6 @@ it { is_expected.to belong_to(:license) } - it { is_expected.to validate_presence_of(:license) } it { is_expected.to validate_presence_of(:class_name) } it { is_expected.to validate_uniqueness_of(:class_name).scoped_to(:license_id) } diff --git a/spec/models/combo_choice_answer_spec.rb b/spec/models/combo_choice_answer_spec.rb index b1f612d8..ae65371c 100644 --- a/spec/models/combo_choice_answer_spec.rb +++ b/spec/models/combo_choice_answer_spec.rb @@ -7,9 +7,6 @@ it { is_expected.to belong_to(:combo_choice) } it { is_expected.to belong_to(:answer) } - it { is_expected.to validate_presence_of(:combo_choice) } - it { is_expected.to validate_presence_of(:answer) } - it { is_expected.to validate_uniqueness_of(:answer).scoped_to(:combo_choice_id) } it 'should require answer and combo_choice to have the same question' do diff --git a/spec/models/combo_choice_spec.rb b/spec/models/combo_choice_spec.rb index 6135bb22..5a9e227b 100644 --- a/spec/models/combo_choice_spec.rb +++ b/spec/models/combo_choice_spec.rb @@ -6,7 +6,6 @@ it { is_expected.to have_many(:combo_choice_answers).dependent(:destroy) } - it { is_expected.to validate_presence_of(:stem) } it { is_expected.to validate_presence_of(:correctness) } it { is_expected.to validate_numericality_of(:correctness) } diff --git a/spec/models/copyright_holder_spec.rb b/spec/models/copyright_holder_spec.rb index 00ac4373..ebb927f3 100644 --- a/spec/models/copyright_holder_spec.rb +++ b/spec/models/copyright_holder_spec.rb @@ -7,9 +7,6 @@ it { is_expected.to belong_to(:publication) } it { is_expected.to belong_to(:user) } - it { is_expected.to validate_presence_of(:publication) } - it { is_expected.to validate_presence_of(:user) } - it { is_expected.to delegate_method(:name).to(:user) } it 'requires a unique user for each publication' do diff --git a/spec/models/deputization_spec.rb b/spec/models/deputization_spec.rb index 2dbc0317..0b97c4cb 100644 --- a/spec/models/deputization_spec.rb +++ b/spec/models/deputization_spec.rb @@ -5,9 +5,6 @@ it { is_expected.to belong_to(:deputy) } it { is_expected.to belong_to(:deputizer) } - it { is_expected.to validate_presence_of(:deputy) } - it { is_expected.to validate_presence_of(:deputizer) } - it 'requires a unique deputizer for each deputy' do deputization_1 = FactoryBot.create :deputization deputization_2 = FactoryBot.build :deputization, diff --git a/spec/models/derivation_spec.rb b/spec/models/derivation_spec.rb index 63079537..912719ce 100644 --- a/spec/models/derivation_spec.rb +++ b/spec/models/derivation_spec.rb @@ -5,9 +5,7 @@ subject(:derivation) { FactoryBot.create :derivation } it { is_expected.to belong_to(:derived_publication) } - it { is_expected.to belong_to(:source_publication) } - - it { is_expected.to validate_presence_of(:derived_publication) } + it { is_expected.to belong_to(:source_publication).optional } it 'requires a unique source_publication for each derived_publication' do derivation_2 = FactoryBot.build(:derivation, diff --git a/spec/models/exercise_tag_spec.rb b/spec/models/exercise_tag_spec.rb index f7c27b89..85db1952 100644 --- a/spec/models/exercise_tag_spec.rb +++ b/spec/models/exercise_tag_spec.rb @@ -6,8 +6,5 @@ it { is_expected.to belong_to(:exercise) } it { is_expected.to belong_to(:tag) } - it { is_expected.to validate_presence_of(:exercise) } - it { is_expected.to validate_presence_of(:tag) } - it { is_expected.to validate_uniqueness_of(:tag).scoped_to(:exercise_id) } end diff --git a/spec/models/hint_spec.rb b/spec/models/hint_spec.rb index d761581e..7c7d06b2 100644 --- a/spec/models/hint_spec.rb +++ b/spec/models/hint_spec.rb @@ -4,7 +4,6 @@ it { is_expected.to belong_to(:question) } - it { is_expected.to validate_presence_of(:question) } it { is_expected.to validate_presence_of(:content) } end diff --git a/spec/models/license_compatibility_spec.rb b/spec/models/license_compatibility_spec.rb index 6998cb0e..4e0f1db7 100644 --- a/spec/models/license_compatibility_spec.rb +++ b/spec/models/license_compatibility_spec.rb @@ -7,9 +7,6 @@ it { is_expected.to belong_to(:original_license) } it { is_expected.to belong_to(:combined_license) } - it { is_expected.to validate_presence_of(:original_license) } - it { is_expected.to validate_presence_of(:combined_license) } - it { is_expected.to validate_uniqueness_of(:combined_license).scoped_to(:original_license_id) } end diff --git a/spec/models/list_editor_spec.rb b/spec/models/list_editor_spec.rb index 52ddde8f..cb0f505b 100644 --- a/spec/models/list_editor_spec.rb +++ b/spec/models/list_editor_spec.rb @@ -5,9 +5,6 @@ it { is_expected.to belong_to(:list) } it { is_expected.to belong_to(:editor) } - it { is_expected.to validate_presence_of(:list) } - it { is_expected.to validate_presence_of(:editor) } - it 'requires a unique editor for each list' do list_editor_1 = FactoryBot.create :list_editor list_editor_2 = FactoryBot.build :list_editor, diff --git a/spec/models/list_nesting_spec.rb b/spec/models/list_nesting_spec.rb index f39fb14f..d0abfbfe 100644 --- a/spec/models/list_nesting_spec.rb +++ b/spec/models/list_nesting_spec.rb @@ -7,9 +7,6 @@ it { is_expected.to belong_to(:parent_list) } it { is_expected.to belong_to(:child_list) } - it { is_expected.to validate_presence_of(:parent_list) } - it { is_expected.to validate_presence_of(:child_list) } - it { is_expected.to validate_uniqueness_of(:child_list) } end diff --git a/spec/models/list_owner_spec.rb b/spec/models/list_owner_spec.rb index d3a12966..d89b1a23 100644 --- a/spec/models/list_owner_spec.rb +++ b/spec/models/list_owner_spec.rb @@ -5,9 +5,6 @@ it { is_expected.to belong_to(:list) } it { is_expected.to belong_to(:owner) } - it { is_expected.to validate_presence_of(:list) } - it { is_expected.to validate_presence_of(:owner) } - it 'requires a unique owner for each list' do list_owner_1 = FactoryBot.create :list_owner list_owner_2 = FactoryBot.build :list_owner, diff --git a/spec/models/list_publication_group_spec.rb b/spec/models/list_publication_group_spec.rb index ce6a2625..37bbe45c 100644 --- a/spec/models/list_publication_group_spec.rb +++ b/spec/models/list_publication_group_spec.rb @@ -7,9 +7,6 @@ it { is_expected.to belong_to(:list) } it { is_expected.to belong_to(:publication_group) } - it { is_expected.to validate_presence_of(:list) } - it { is_expected.to validate_presence_of(:publication_group) } - it { is_expected.to validate_uniqueness_of(:publication_group).scoped_to(:list_id) } end diff --git a/spec/models/list_reader_spec.rb b/spec/models/list_reader_spec.rb index 4e6078c1..878b4a63 100644 --- a/spec/models/list_reader_spec.rb +++ b/spec/models/list_reader_spec.rb @@ -5,9 +5,6 @@ it { is_expected.to belong_to(:list) } it { is_expected.to belong_to(:reader) } - it { is_expected.to validate_presence_of(:list) } - it { is_expected.to validate_presence_of(:reader) } - it 'requires a unique reader for each list' do list_reader_1 = FactoryBot.create :list_reader list_reader_2 = FactoryBot.build :list_reader, diff --git a/spec/models/logic_spec.rb b/spec/models/logic_spec.rb index 25ec3dee..2cc015dd 100644 --- a/spec/models/logic_spec.rb +++ b/spec/models/logic_spec.rb @@ -6,7 +6,6 @@ it { is_expected.to have_many(:logic_variables) } - it { is_expected.to validate_presence_of(:parent) } it { is_expected.to validate_presence_of(:language) } it { is_expected.to validate_presence_of(:code) } diff --git a/spec/models/logic_variable_spec.rb b/spec/models/logic_variable_spec.rb index 5c2f005b..e8d6b49f 100644 --- a/spec/models/logic_variable_spec.rb +++ b/spec/models/logic_variable_spec.rb @@ -11,7 +11,6 @@ it { is_expected.to have_many(:logic_variable_values).dependent(:destroy) } - it { is_expected.to validate_presence_of(:logic) } it { is_expected.to validate_presence_of(:variable) } it { is_expected.to validate_uniqueness_of(:variable).scoped_to(:logic_id) } diff --git a/spec/models/logic_variable_value_spec.rb b/spec/models/logic_variable_value_spec.rb index 04d67ddd..8a2cd31c 100644 --- a/spec/models/logic_variable_value_spec.rb +++ b/spec/models/logic_variable_value_spec.rb @@ -6,7 +6,6 @@ it { is_expected.to belong_to(:logic_variable) } - it { is_expected.to validate_presence_of(:logic_variable) } it { is_expected.to validate_presence_of(:seed) } it { is_expected.to validate_presence_of(:value) } diff --git a/spec/models/publication_spec.rb b/spec/models/publication_spec.rb index 3bd21629..3640af62 100644 --- a/spec/models/publication_spec.rb +++ b/spec/models/publication_spec.rb @@ -6,7 +6,7 @@ it { is_expected.to belong_to(:publication_group) } it { is_expected.to belong_to(:publishable) } - it { is_expected.to belong_to(:license) } + it { is_expected.to belong_to(:license).optional } it { is_expected.to have_many(:authors).dependent(:destroy) } it { is_expected.to have_many(:copyright_holders).dependent(:destroy) } @@ -14,9 +14,6 @@ it { is_expected.to have_many(:sources).dependent(:destroy) } it { is_expected.to have_many(:derivations).dependent(:destroy) } - it { is_expected.to validate_presence_of(:publication_group) } - it { is_expected.to validate_presence_of(:publishable) } - it { is_expected.to validate_uniqueness_of(:uuid).case_insensitive } it { is_expected.to validate_uniqueness_of(:version).scoped_to(:publication_group_id) } diff --git a/spec/models/question_dependency_spec.rb b/spec/models/question_dependency_spec.rb index c2112c3f..a77e98eb 100644 --- a/spec/models/question_dependency_spec.rb +++ b/spec/models/question_dependency_spec.rb @@ -7,9 +7,6 @@ it { is_expected.to belong_to(:parent_question) } it { is_expected.to belong_to(:dependent_question) } - it { is_expected.to validate_presence_of(:parent_question) } - it { is_expected.to validate_presence_of(:dependent_question) } - it { is_expected.to validate_uniqueness_of(:dependent_question).scoped_to(:parent_question_id) } it 'requires both questions to belong to the same exercise' do diff --git a/spec/models/question_spec.rb b/spec/models/question_spec.rb index 723253cf..55b8ed26 100644 --- a/spec/models/question_spec.rb +++ b/spec/models/question_spec.rb @@ -12,6 +12,6 @@ it { is_expected.to have_many(:parent_dependencies).dependent(:destroy) } it { is_expected.to have_many(:child_dependencies).dependent(:destroy) } - it { is_expected.to validate_presence_of(:exercise) } + it { is_expected.to belong_to(:exercise) } end diff --git a/spec/models/stem_answer_spec.rb b/spec/models/stem_answer_spec.rb index f48243f7..fbd8b650 100644 --- a/spec/models/stem_answer_spec.rb +++ b/spec/models/stem_answer_spec.rb @@ -7,8 +7,6 @@ it { is_expected.to belong_to(:stem) } it { is_expected.to belong_to(:answer) } - it { is_expected.to validate_presence_of(:stem) } - it { is_expected.to validate_presence_of(:answer) } it { is_expected.to validate_presence_of(:correctness) } it { is_expected.to validate_uniqueness_of(:answer).scoped_to(:stem_id) } diff --git a/spec/models/stem_spec.rb b/spec/models/stem_spec.rb index 896a0ee1..2e0883a7 100644 --- a/spec/models/stem_spec.rb +++ b/spec/models/stem_spec.rb @@ -8,7 +8,6 @@ it { is_expected.to have_many(:combo_choices).dependent(:destroy) } - it { is_expected.to validate_presence_of(:question) } it { is_expected.to validate_presence_of(:content) } end diff --git a/spec/models/styling_spec.rb b/spec/models/styling_spec.rb index 2868daa2..2c6ac1c1 100644 --- a/spec/models/styling_spec.rb +++ b/spec/models/styling_spec.rb @@ -4,7 +4,6 @@ it { is_expected.to belong_to(:stylable) } - it { is_expected.to validate_presence_of(:stylable) } it { is_expected.to validate_presence_of(:style) } it { is_expected.to validate_inclusion_of(:style).in_array(Style.all) } diff --git a/spec/models/trusted_application_spec.rb b/spec/models/trusted_application_spec.rb index 790144dd..0a4e84ae 100644 --- a/spec/models/trusted_application_spec.rb +++ b/spec/models/trusted_application_spec.rb @@ -6,8 +6,6 @@ it { is_expected.to belong_to(:application) } - it { is_expected.to validate_presence_of(:application) } - it { is_expected.to validate_uniqueness_of(:application) } end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f7f90883..f16862f3 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -23,8 +23,6 @@ it { is_expected.to have_many(:direct_applications).dependent(:destroy) } - it { is_expected.to validate_presence_of(:account) } - it { is_expected.to validate_uniqueness_of(:account) } [ :username, :first_name, :last_name, :full_name, diff --git a/spec/models/vocab_distractor_spec.rb b/spec/models/vocab_distractor_spec.rb index 06d49db0..849ad0d9 100644 --- a/spec/models/vocab_distractor_spec.rb +++ b/spec/models/vocab_distractor_spec.rb @@ -5,8 +5,7 @@ it { is_expected.to belong_to(:vocab_term) } - it { is_expected.to validate_presence_of(:vocab_term) } - it { is_expected.to validate_presence_of(:distractor_publication_group) } + it { is_expected.to belong_to(:distractor_publication_group) } it { is_expected.to validate_presence_of(:distractor_term) } it do diff --git a/spec/models/vocab_term_tag_spec.rb b/spec/models/vocab_term_tag_spec.rb index c6ae378f..ca727845 100644 --- a/spec/models/vocab_term_tag_spec.rb +++ b/spec/models/vocab_term_tag_spec.rb @@ -6,8 +6,5 @@ it { is_expected.to belong_to(:vocab_term) } it { is_expected.to belong_to(:tag) } - it { is_expected.to validate_presence_of(:vocab_term) } - it { is_expected.to validate_presence_of(:tag) } - it { is_expected.to validate_uniqueness_of(:tag).scoped_to(:vocab_term_id) } end From ec0f8b8ae213daab61502e1cc3f8d084e2caff31 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Wed, 5 Jun 2019 17:46:46 -0500 Subject: [PATCH 34/50] ActionController::Parameters deprecation fix --- spec/controllers/oauth/applications_controller_spec.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb index c497c5d5..fd55c01d 100644 --- a/spec/controllers/oauth/applications_controller_spec.rb +++ b/spec/controllers/oauth/applications_controller_spec.rb @@ -114,22 +114,23 @@ module Oauth context "PATCH update" do context "with valid params" do + dummy_params = ActionController::Parameters.new({ "name" => "Dummy" }).permit! it "updates the requested application" do expect_any_instance_of(Doorkeeper::Application) - .to receive(:update_attributes).with({ "name" => "Dummy" }) + .to receive(:update_attributes).with(dummy_params) patch :update, params: {id: group_1_application_1.to_param, - doorkeeper_application: { "name" => "Dummy" }}, session: valid_session + doorkeeper_application: dummy_params}, session: valid_session end it "assigns the requested application as @application" do patch :update, params: {id: group_1_application_1.to_param, - doorkeeper_application: { "name" => "Dummy" }}, session: valid_session + doorkeeper_application: dummy_params}, session: valid_session expect(assigns(:application)).to eq(group_1_application_1) end it "redirects to the application" do patch :update, params: {id: group_1_application_1.to_param, - doorkeeper_application: { "name" => "Dummy" }}, session: valid_session + doorkeeper_application: dummy_params}, session: valid_session expect(response).to redirect_to( oauth_application_url(group_1_application_1) ) From 3aa6af7cd9017b46bd6ec4d1a27a4bd85257a7a1 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 6 Jun 2019 11:46:15 -0500 Subject: [PATCH 35/50] Rails 5.1 updates - mostly config secret key access changes and gem updates --- Gemfile | 4 +- Gemfile.lock | 88 +++++++++---------- bin/setup | 4 + config/application.rb | 12 +-- config/boot.rb | 2 +- config/cable.yml | 1 + config/environment.rb | 2 +- config/environments/test.rb | 2 +- config/initializers/a15k.rb | 8 +- config/initializers/amazon_ses.rb | 8 +- config/initializers/assets.rb | 5 ++ config/initializers/carrierwave.rb | 16 ++-- config/initializers/new_framework_defaults.rb | 25 ------ config/initializers/openstax_accounts.rb | 10 +-- config/initializers/rescue_from.rb | 2 +- config/locales/en.yml | 10 +++ config/puma.rb | 23 +++-- 17 files changed, 113 insertions(+), 109 deletions(-) delete mode 100644 config/initializers/new_framework_defaults.rb diff --git a/Gemfile b/Gemfile index 6e0afe29..e1b17bcd 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ git_source(:github) do |repo_name| end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 5.0.7.2' +gem 'rails', '~> 5.1.7' # Bootstrap gem 'bootstrap-sass' @@ -24,7 +24,7 @@ gem 'compass-rails' gem 'uglifier', '>= 1.3.0' # Use CoffeeScript for .coffee assets and views -gem 'coffee-rails', '~> 4.1.0' +gem 'coffee-rails', '~> 4.2.2' gem 'mini_racer' diff --git a/Gemfile.lock b/Gemfile.lock index bbfe7bdc..42b902c8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,42 +13,42 @@ GEM specs: action_interceptor (1.1.2) rails (>= 3.1) - actioncable (5.0.7.2) - actionpack (= 5.0.7.2) - nio4r (>= 1.2, < 3.0) + actioncable (5.1.7) + actionpack (= 5.1.7) + nio4r (~> 2.0) websocket-driver (~> 0.6.1) - actionmailer (5.0.7.2) - actionpack (= 5.0.7.2) - actionview (= 5.0.7.2) - activejob (= 5.0.7.2) + actionmailer (5.1.7) + actionpack (= 5.1.7) + actionview (= 5.1.7) + activejob (= 5.1.7) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.0.7.2) - actionview (= 5.0.7.2) - activesupport (= 5.0.7.2) + actionpack (5.1.7) + actionview (= 5.1.7) + activesupport (= 5.1.7) rack (~> 2.0) - rack-test (~> 0.6.3) + rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.0.7.2) - activesupport (= 5.0.7.2) + actionview (5.1.7) + activesupport (= 5.1.7) builder (~> 3.1) - erubis (~> 2.7.0) + erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) active_attr (0.13.1) activemodel (>= 3.0.2, < 6.1) activesupport (>= 3.0.2, < 6.1) - activejob (5.0.7.2) - activesupport (= 5.0.7.2) + activejob (5.1.7) + activesupport (= 5.1.7) globalid (>= 0.3.6) - activemodel (5.0.7.2) - activesupport (= 5.0.7.2) - activerecord (5.0.7.2) - activemodel (= 5.0.7.2) - activesupport (= 5.0.7.2) - arel (~> 7.0) - activesupport (5.0.7.2) + activemodel (5.1.7) + activesupport (= 5.1.7) + activerecord (5.1.7) + activemodel (= 5.1.7) + activesupport (= 5.1.7) + arel (~> 8.0) + activesupport (5.1.7) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -58,7 +58,7 @@ GEM public_suffix (>= 2.0.2, < 4.0) apipie-rails (0.5.16) rails (>= 4.1) - arel (7.1.4) + arel (8.0.0) ast (2.4.0) autoprefixer-rails (9.5.1.1) execjs @@ -89,9 +89,9 @@ GEM json simplecov url - coffee-rails (4.1.1) + coffee-rails (4.2.2) coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.1.x) + railties (>= 4.0.0) coffee-rails-source-maps (1.4.0) coffee-script-source (>= 1.6.1) coffee-script (2.4.1) @@ -139,7 +139,7 @@ GEM execjs eco-source (1.1.0.rc.1) ejs (1.1.1) - erubis (2.7.0) + erubi (1.8.0) ethon (0.12.0) ffi (>= 1.3.0) eventmachine (1.2.7) @@ -298,20 +298,20 @@ GEM pg (0.21.0) public_suffix (3.1.0) rack (2.0.7) - rack-test (0.6.3) - rack (>= 1.0) + rack-test (1.1.0) + rack (>= 1.0, < 3) railroady (1.5.3) - rails (5.0.7.2) - actioncable (= 5.0.7.2) - actionmailer (= 5.0.7.2) - actionpack (= 5.0.7.2) - actionview (= 5.0.7.2) - activejob (= 5.0.7.2) - activemodel (= 5.0.7.2) - activerecord (= 5.0.7.2) - activesupport (= 5.0.7.2) + rails (5.1.7) + actioncable (= 5.1.7) + actionmailer (= 5.1.7) + actionpack (= 5.1.7) + actionview (= 5.1.7) + activejob (= 5.1.7) + activemodel (= 5.1.7) + activerecord (= 5.1.7) + activesupport (= 5.1.7) bundler (>= 1.3.0) - railties (= 5.0.7.2) + railties (= 5.1.7) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.4) actionpack (>= 5.0.1.x) @@ -327,9 +327,9 @@ GEM ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.4) loofah (~> 2.2, >= 2.2.2) - railties (5.0.7.2) - actionpack (= 5.0.7.2) - activesupport (= 5.0.7.2) + railties (5.1.7) + actionpack (= 5.1.7) + activesupport (= 5.1.7) method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) @@ -510,7 +510,7 @@ DEPENDENCIES cheat codeclimate-test-reporter codecov - coffee-rails (~> 4.1.0) + coffee-rails (~> 4.2.2) coffee-rails-source-maps commontator compass-rails @@ -547,7 +547,7 @@ DEPENDENCIES parallel_tests pg (~> 0.18) railroady - rails (~> 5.0.7.2) + rails (~> 5.1.7) rails-controller-testing rails-erd rails-html-sanitizer diff --git a/bin/setup b/bin/setup index e620b4da..78c4e861 100755 --- a/bin/setup +++ b/bin/setup @@ -18,6 +18,10 @@ chdir APP_ROOT do system! 'gem install bundler --conservative' system('bundle check') || system!('bundle install') + # Install JavaScript dependencies if using Yarn + # system('bin/yarn') + + # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') # cp 'config/database.yml.sample', 'config/database.yml' diff --git a/config/application.rb b/config/application.rb index 5315560b..1e2ac054 100644 --- a/config/application.rb +++ b/config/application.rb @@ -11,6 +11,9 @@ module Exercises class Application < Rails::Application + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 5.1 + # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. @@ -27,10 +30,10 @@ class Application < Rails::Application # Set the default cache store to Redis # This setting cannot be set from an initializer # See https://github.com/rails/rails/issues/10908 - redis_secrets = secrets['redis'] + redis_secrets = secrets[:redis] config.cache_store = :redis_store, { - url: redis_secrets['url'], - namespace: redis_secrets['namespaces']['cache'], + url: redis_secrets[:url], + namespace: redis_secrets[:namespaces][:cache], expires_in: 1.day, compress: true, compress_threshold: 1.kilobyte @@ -38,6 +41,3 @@ class Application < Rails::Application end end - -# Require `belongs_to` associations by default. Previous versions had false. -Rails.application.config.active_record.belongs_to_required_by_default = true diff --git a/config/boot.rb b/config/boot.rb index 128c941b..30f5120d 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,3 +1,3 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) -require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/cable.yml b/config/cable.yml index 0bbde6f7..db66ede1 100644 --- a/config/cable.yml +++ b/config/cable.yml @@ -7,3 +7,4 @@ test: production: adapter: redis url: redis://localhost:6379/1 + channel_prefix: exercises_production diff --git a/config/environment.rb b/config/environment.rb index d928e4d5..ee1e514b 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -31,5 +31,5 @@ SITE_NAME = "OpenStax Exercises" COPYRIGHT_HOLDER = "Rice University" -# Initialize the rails application +# Initialize the Rails application Exercises::Application.initialize! diff --git a/config/environments/test.rb b/config/environments/test.rb index 32fd8d49..af95530b 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -15,7 +15,7 @@ # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true config.public_file_server.headers = { - 'Cache-Control' => 'public, max-age=3600' + 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}" } # Show full error reports and disable caching. diff --git a/config/initializers/a15k.rb b/config/initializers/a15k.rb index 5ced0505..1301766d 100644 --- a/config/initializers/a15k.rb +++ b/config/initializers/a15k.rb @@ -1,7 +1,7 @@ -secrets = Rails.application.secrets['a15k'] +secrets = Rails.application.secrets[:a15k] A15kClient.configure do |c| - c.scheme = secrets['scheme'] - c.host = secrets['host'] - c.api_key['Authorization'] = secrets['access_token'] + c.scheme = secrets[:scheme] + c.host = secrets[:host] + c.api_key['Authorization'] = secrets[:access_token] end unless secrets.nil? diff --git a/config/initializers/amazon_ses.rb b/config/initializers/amazon_ses.rb index 2a04fde2..9781ccae 100644 --- a/config/initializers/amazon_ses.rb +++ b/config/initializers/amazon_ses.rb @@ -1,11 +1,11 @@ if Rails.env.production? - secrets = Rails.application.secrets['aws']['ses'] + secrets = Rails.application.secrets[:aws][:ses] ActionMailer::Base.add_delivery_method( :ses, AWS::SES::Base, - access_key_id: secrets['access_key_id'], - secret_access_key: secrets['secret_access_key'], - server: secrets['endpoint_server'] + access_key_id: secrets[:access_key_id], + secret_access_key: secrets[:secret_access_key], + server: secrets[:endpoint_server] ) end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 383a47b1..802465c5 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -3,6 +3,11 @@ # Version of your assets, change this if you want to expire all your assets. Rails.application.config.assets.version = '1.0' +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path +# Add Yarn node_modules folder to the asset load path. +Rails.application.config.assets.paths << Rails.root.join('node_modules') + # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. # Rails.application.config.assets.precompile += %w( search.js ) diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index c7656acb..145199b0 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -6,24 +6,24 @@ # Upload to AWS only in the production environment config.storage = if Rails.env.production? - secrets = Rails.application.secrets['aws']['s3'] + secrets = Rails.application.secrets[:aws][:s3] - config.asset_host = secrets['asset_host'] + config.asset_host = secrets[:asset_host] config.fog_attributes = { 'Cache-Control' => 'max-age=31536000' } - config.fog_directory = secrets['bucket_name'] + config.fog_directory = secrets[:bucket_name] config.fog_provider = 'fog/aws' - fog_credentials = secrets['access_key_id'].blank? ? \ + fog_credentials = secrets[:access_key_id].blank? ? \ { use_iam_profile: true } : \ - { aws_access_key_id: secrets['access_key_id'], - aws_secret_access_key: secrets['secret_access_key'] } + { aws_access_key_id: secrets[:access_key_id], + aws_secret_access_key: secrets[:secret_access_key] } config.fog_credentials = fog_credentials.merge( provider: 'AWS', - region: secrets['region'], - endpoint: secrets['endpoint_server'] + region: secrets[:region], + endpoint: secrets[:endpoint_server] ) :fog diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb deleted file mode 100644 index 9663f82e..00000000 --- a/config/initializers/new_framework_defaults.rb +++ /dev/null @@ -1,25 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file contains migration options to ease your Rails 5.0 upgrade. -# -# Once upgraded flip defaults one by one to migrate to the new default. -# -# Read the Guide for Upgrading Ruby on Rails for more info on each option. - -Rails.application.config.action_controller.raise_on_unfiltered_parameters = false - -# Enable per-form CSRF tokens. Previous versions had false. -Rails.application.config.action_controller.per_form_csrf_tokens = true - -# Enable origin-checking CSRF mitigation. Previous versions had false. -Rails.application.config.action_controller.forgery_protection_origin_check = true - -# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. -# Previous versions had false. -ActiveSupport.to_time_preserves_timezone = true - -# Require `belongs_to` associations by default. Previous versions had false. -Rails.application.config.active_record.belongs_to_required_by_default = true - -# Do not halt callback chains when a callback returns false. Previous versions had true. -ActiveSupport.halt_callback_chains_on_return_false = false diff --git a/config/initializers/openstax_accounts.rb b/config/initializers/openstax_accounts.rb index 32576722..17222adc 100644 --- a/config/initializers/openstax_accounts.rb +++ b/config/initializers/openstax_accounts.rb @@ -1,14 +1,14 @@ require 'user_mapper' -secrets = Rails.application.secrets['openstax']['accounts'] +secrets = Rails.application.secrets[:openstax][:accounts] # By default, stub unless in the production environment -stub = secrets['stub'].nil? ? !Rails.env.production? : secrets['stub'] +stub = secrets[:stub].nil? ? !Rails.env.production? : secrets[:stub] OpenStax::Accounts.configure do |config| - config.openstax_application_id = secrets['client_id'] - config.openstax_application_secret = secrets['secret'] - config.openstax_accounts_url = secrets['url'] + config.openstax_application_id = secrets[:client_id] + config.openstax_application_secret = secrets[:secret] + config.openstax_accounts_url = secrets[:url] config.enable_stubbing = stub config.logout_via = :delete config.account_user_mapper = UserMapper diff --git a/config/initializers/rescue_from.rb b/config/initializers/rescue_from.rb index 79ec6f34..c88aed4c 100644 --- a/config/initializers/rescue_from.rb +++ b/config/initializers/rescue_from.rb @@ -6,7 +6,7 @@ config.raise_exceptions = Rails.application.config.consider_all_requests_local config.app_name = 'Exercises' - config.contact_name = exception_secrets['contact_name'] + config.contact_name = exception_secrets[:contact_name] # Notify devs using sentry-raven config.notify_proc = ->(proxy, controller) do diff --git a/config/locales/en.yml b/config/locales/en.yml index 06539571..decc5a85 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -16,6 +16,16 @@ # # This would use the information in config/locales/es.yml. # +# The following keys must be escaped otherwise they will not be retrieved by +# the default I18n backend: +# +# true, false, on, off, yes, no +# +# Instead, surround them with single quotes. +# +# en: +# 'true': 'foo' +# # To learn more, please read the Rails Internationalization guide # available at http://guides.rubyonrails.org/i18n.html. diff --git a/config/puma.rb b/config/puma.rb index c7f311f8..1e19380d 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,13 +1,13 @@ # Puma can serve each request in a thread from an internal thread pool. -# The `threads` method setting takes two numbers a minimum and maximum. +# The `threads` method setting takes two numbers: a minimum and maximum. # Any libraries that use thread pools should be configured to match # the maximum value specified for Puma. Default is set to 5 threads for minimum -# and maximum, this matches the default thread size of Active Record. +# and maximum; this matches the default thread size of Active Record. # -threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } threads threads_count, threads_count -# Specifies the `port` that Puma will listen on to receive requests, default is 3000. +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. # port ENV.fetch("PORT") { 3000 } @@ -32,16 +32,25 @@ # # preload_app! +# If you are preloading your application and using Active Record, it's +# recommended that you close any connections to the database before workers +# are forked to prevent connection leakage. +# +# before_fork do +# ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) +# end + # The code in the `on_worker_boot` will be called if you are using # clustered mode by specifying a number of `workers`. After each worker -# process is booted this block will be run, if you are using `preload_app!` -# option you will want to use this block to reconnect to any threads -# or connections that may have been created at application boot, Ruby +# process is booted, this block will be run. If you are using the `preload_app!` +# option, you will want to use this block to reconnect to any threads +# or connections that may have been created at application boot, as Ruby # cannot share connections between processes. # # on_worker_boot do # ActiveRecord::Base.establish_connection if defined?(ActiveRecord) # end +# # Allow puma to be restarted by `rails restart` command. plugin :tmp_restart From a94596e6e890f8b30f5c4b9852897b9d292eb4fd Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 6 Jun 2019 14:17:51 -0500 Subject: [PATCH 36/50] gem version bumps for 5.2; remove one error class --- Gemfile | 5 +- Gemfile.lock | 89 +++++++++++-------- app/views/admin/console/_misc.html.erb | 2 - bin/bundle | 2 +- bin/setup | 4 +- config/boot.rb | 1 + config/cable.yml | 2 +- config/environments/development.rb | 3 + .../application_controller_renderer.rb | 8 +- .../initializers/content_security_policy.rb | 25 ++++++ config/initializers/wrap_parameters.rb | 2 +- config/storage.yml | 34 +++++++ .../admin/exceptions_controller_spec.rb | 1 - 13 files changed, 125 insertions(+), 53 deletions(-) create mode 100644 config/initializers/content_security_policy.rb create mode 100644 config/storage.yml diff --git a/Gemfile b/Gemfile index e1b17bcd..3356651d 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ git_source(:github) do |repo_name| end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 5.1.7' +gem 'rails', '~> 5.2' # Bootstrap gem 'bootstrap-sass' @@ -155,6 +155,9 @@ gem 'redis-rails' # Respond to ELB healthchecks in /ping and /ping/ gem 'openstax_healthcheck' +# Reduces boot times through caching; required in config/boot.rb +gem 'bootsnap', '~> 1.4.0', require: false + group :development, :test do # Get env variables from .env file gem 'dotenv-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 42b902c8..b69b8131 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,25 +13,25 @@ GEM specs: action_interceptor (1.1.2) rails (>= 3.1) - actioncable (5.1.7) - actionpack (= 5.1.7) + actioncable (5.2.3) + actionpack (= 5.2.3) nio4r (~> 2.0) - websocket-driver (~> 0.6.1) - actionmailer (5.1.7) - actionpack (= 5.1.7) - actionview (= 5.1.7) - activejob (= 5.1.7) + websocket-driver (>= 0.6.1) + actionmailer (5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.1.7) - actionview (= 5.1.7) - activesupport (= 5.1.7) + actionpack (5.2.3) + actionview (= 5.2.3) + activesupport (= 5.2.3) rack (~> 2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.1.7) - activesupport (= 5.1.7) + actionview (5.2.3) + activesupport (= 5.2.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -39,16 +39,20 @@ GEM active_attr (0.13.1) activemodel (>= 3.0.2, < 6.1) activesupport (>= 3.0.2, < 6.1) - activejob (5.1.7) - activesupport (= 5.1.7) + activejob (5.2.3) + activesupport (= 5.2.3) globalid (>= 0.3.6) - activemodel (5.1.7) - activesupport (= 5.1.7) - activerecord (5.1.7) - activemodel (= 5.1.7) - activesupport (= 5.1.7) - arel (~> 8.0) - activesupport (5.1.7) + activemodel (5.2.3) + activesupport (= 5.2.3) + activerecord (5.2.3) + activemodel (= 5.2.3) + activesupport (= 5.2.3) + arel (>= 9.0) + activestorage (5.2.3) + actionpack (= 5.2.3) + activerecord (= 5.2.3) + marcel (~> 0.3.1) + activesupport (5.2.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -58,9 +62,9 @@ GEM public_suffix (>= 2.0.2, < 4.0) apipie-rails (0.5.16) rails (>= 4.1) - arel (8.0.0) + arel (9.0.0) ast (2.4.0) - autoprefixer-rails (9.5.1.1) + autoprefixer-rails (9.6.0) execjs aws-ses (0.6.0) builder @@ -68,6 +72,8 @@ GEM mime-types xml-simple bindex (0.7.0) + bootsnap (1.4.4) + msgpack (~> 1.0) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) @@ -222,6 +228,8 @@ GEM nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) maruku (0.7.3) method_source (0.9.2) mime-types (3.2.2) @@ -234,6 +242,7 @@ GEM mini_racer (0.2.6) libv8 (>= 6.9.411) minitest (5.11.3) + msgpack (1.2.10) multi_json (1.13.1) multi_xml (0.6.0) multipart-post (2.1.1) @@ -301,17 +310,18 @@ GEM rack-test (1.1.0) rack (>= 1.0, < 3) railroady (1.5.3) - rails (5.1.7) - actioncable (= 5.1.7) - actionmailer (= 5.1.7) - actionpack (= 5.1.7) - actionview (= 5.1.7) - activejob (= 5.1.7) - activemodel (= 5.1.7) - activerecord (= 5.1.7) - activesupport (= 5.1.7) + rails (5.2.3) + actioncable (= 5.2.3) + actionmailer (= 5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) + activemodel (= 5.2.3) + activerecord (= 5.2.3) + activestorage (= 5.2.3) + activesupport (= 5.2.3) bundler (>= 1.3.0) - railties (= 5.1.7) + railties (= 5.2.3) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.4) actionpack (>= 5.0.1.x) @@ -327,12 +337,12 @@ GEM ruby-graphviz (~> 1.2) rails-html-sanitizer (1.0.4) loofah (~> 2.2, >= 2.2.2) - railties (5.1.7) - actionpack (= 5.1.7) - activesupport (= 5.1.7) + railties (5.2.3) + actionpack (= 5.2.3) + activesupport (= 5.2.3) method_source rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) + thor (>= 0.19.0, < 2.0) rainbow (3.0.0) raindrops (0.19.0) rake (12.3.2) @@ -486,7 +496,7 @@ GEM activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) - websocket-driver (0.6.5) + websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) whenever (0.11.0) @@ -503,6 +513,7 @@ DEPENDENCIES apipie-rails autoprefixer-rails aws-ses (~> 0.6.0) + bootsnap (~> 1.4.0) bootstrap-sass brakeman byebug @@ -547,7 +558,7 @@ DEPENDENCIES parallel_tests pg (~> 0.18) railroady - rails (~> 5.1.7) + rails (~> 5.2) rails-controller-testing rails-erd rails-html-sanitizer diff --git a/app/views/admin/console/_misc.html.erb b/app/views/admin/console/_misc.html.erb index 02bb22b4..1b036575 100644 --- a/app/views/admin/console/_misc.html.erb +++ b/app/views/admin/console/_misc.html.erb @@ -7,8 +7,6 @@

  • <%= link_to 'ActionController::RoutingError', admin_exception_url('ActionController::RoutingError', args: '/blah/blah/blah'.inspect) %>
  • -
  • <%= link_to 'ActionController::UnknownController', - admin_exception_url('ActionController::UnknownController') %>
  • <%= link_to 'AbstractController::ActionNotFound', admin_exception_url('AbstractController::ActionNotFound') %>
  • <%= link_to 'ActionView::MissingTemplate', diff --git a/bin/bundle b/bin/bundle index 66e9889e..f19acf5b 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,3 @@ #!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) load Gem.bin_path('bundler', 'bundle') diff --git a/bin/setup b/bin/setup index 78c4e861..94fd4d79 100755 --- a/bin/setup +++ b/bin/setup @@ -1,10 +1,9 @@ #!/usr/bin/env ruby -require 'pathname' require 'fileutils' include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) +APP_ROOT = File.expand_path('..', __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -21,7 +20,6 @@ chdir APP_ROOT do # Install JavaScript dependencies if using Yarn # system('bin/yarn') - # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') # cp 'config/database.yml.sample', 'config/database.yml' diff --git a/config/boot.rb b/config/boot.rb index 30f5120d..b9e460ce 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,3 +1,4 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require 'bundler/setup' # Set up gems listed in the Gemfile. +require 'bootsnap/setup' # Speed up boot time by caching expensive operations. diff --git a/config/cable.yml b/config/cable.yml index db66ede1..1ac654de 100644 --- a/config/cable.yml +++ b/config/cable.yml @@ -6,5 +6,5 @@ test: production: adapter: redis - url: redis://localhost:6379/1 + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> channel_prefix: exercises_production diff --git a/config/environments/development.rb b/config/environments/development.rb index 2fac2693..4f313077 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -26,6 +26,9 @@ # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + # Debug mode disables concatenation and preprocessing of assets. # This option may cause significant delays in view rendering with a large # number of complex assets. diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb index f5e924a6..89d2efab 100644 --- a/config/initializers/application_controller_renderer.rb +++ b/config/initializers/application_controller_renderer.rb @@ -1,8 +1,8 @@ # Be sure to restart your server when you modify this file. # ActiveSupport::Reloader.to_prepare do -# ApplicationController.renderer.defaults.merge!( -# http_host: 'example.org', -# https: false -# ) +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) # end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100644 index 00000000..d3bcaa5e --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy +# For further information see the following documentation +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy + +# Rails.application.config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https + +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end + +# If you are using UJS then enable automatic nonce generation +# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } + +# Report CSP violations to a specified URI +# For further information see the following documentation: +# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# Rails.application.config.content_security_policy_report_only = true diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index cf733efd..bbfc3961 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -10,5 +10,5 @@ # To enable root element in JSON for ActiveRecord objects. # ActiveSupport.on_load(:active_record) do -# self.include_root_in_json = true +# self.include_root_in_json = true # end diff --git a/config/storage.yml b/config/storage.yml new file mode 100644 index 00000000..d32f76e8 --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket + +# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] diff --git a/spec/controllers/admin/exceptions_controller_spec.rb b/spec/controllers/admin/exceptions_controller_spec.rb index eade1876..dc6f31e8 100644 --- a/spec/controllers/admin/exceptions_controller_spec.rb +++ b/spec/controllers/admin/exceptions_controller_spec.rb @@ -6,7 +6,6 @@ module Admin EXCEPTIONS = [[SecurityTransgression], [ActiveRecord::RecordNotFound], [ActionController::RoutingError, '/blah/blah/blah'.inspect], - [ActionController::UnknownController], [AbstractController::ActionNotFound], [ActionView::MissingTemplate, [['a', 'b'], 'path', ['pre1', 'pre2'], From bf94ea84fa82b3201bedbf1ca9c3f8ce12830b62 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Thu, 6 Jun 2019 15:31:12 -0500 Subject: [PATCH 37/50] De-squeel a migration, and update schema --- ...191504_remove_uuid_from_cnxfeature_tags.rb | 2 +- db/schema.rb | 1060 ++++++++--------- 2 files changed, 531 insertions(+), 531 deletions(-) diff --git a/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb b/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb index 9233a695..fd87673a 100644 --- a/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb +++ b/db/migrate/20160610191504_remove_uuid_from_cnxfeature_tags.rb @@ -1,6 +1,6 @@ class RemoveUuidFromCnxfeatureTags < ActiveRecord::Migration[4.2] def up - Tag.where {name.like 'context-cnxfeature:%#%'}.update_all("name = regexp_replace(name, '^context-cnxfeature:[\\w-]+#([\\w-]+)$', 'context-cnxfeature:\\1')") + Tag.where(Tag.arel_table[:name].matches('context-cnxfeature:%#%')).update_all("name = regexp_replace(name, '^context-cnxfeature:[\\w-]+#([\\w-]+)$', 'context-cnxfeature:\\1')") end def down diff --git a/db/schema.rb b/db/schema.rb index 3d67dd80..fd51d613 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,602 +10,602 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20190517204620) do +ActiveRecord::Schema.define(version: 2019_05_17_204620) do # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - enable_extension "pgcrypto" enable_extension "citext" + enable_extension "pgcrypto" + enable_extension "plpgsql" + + create_table "administrators", id: :serial, force: :cascade do |t| + t.integer "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_administrators_on_user_id", unique: true + end - create_table "administrators", force: :cascade do |t| - t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["user_id"], name: "index_administrators_on_user_id", unique: true, using: :btree - end - - create_table "answers", force: :cascade do |t| - t.integer "question_id", null: false - t.text "content", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "sort_position", null: false - t.index ["question_id", "sort_position"], name: "index_answers_on_question_id_and_sort_position", unique: true, using: :btree - end - - create_table "attachments", force: :cascade do |t| - t.integer "parent_id", null: false - t.string "parent_type", null: false - t.string "asset", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["asset"], name: "index_attachments_on_asset", using: :btree - t.index ["parent_id", "parent_type", "asset"], name: "index_attachments_on_parent_id_and_parent_type_and_asset", unique: true, using: :btree - end - - create_table "authors", force: :cascade do |t| - t.integer "sort_position", null: false - t.integer "publication_id", null: false - t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["publication_id", "sort_position"], name: "index_authors_on_publication_id_and_sort_position", unique: true, using: :btree - t.index ["user_id", "publication_id"], name: "index_authors_on_user_id_and_publication_id", unique: true, using: :btree - end - - create_table "class_licenses", force: :cascade do |t| - t.integer "sort_position", null: false - t.integer "license_id", null: false - t.string "class_name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["class_name", "sort_position"], name: "index_class_licenses_on_class_name_and_sort_position", unique: true, using: :btree - t.index ["license_id", "class_name"], name: "index_class_licenses_on_license_id_and_class_name", unique: true, using: :btree - end - - create_table "collaborator_solutions", force: :cascade do |t| - t.integer "question_id", null: false - t.string "title" - t.text "solution_type", null: false - t.text "content", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["question_id"], name: "index_collaborator_solutions_on_question_id", using: :btree - t.index ["solution_type"], name: "index_collaborator_solutions_on_solution_type", using: :btree - t.index ["title"], name: "index_collaborator_solutions_on_title", using: :btree - end - - create_table "combo_choice_answers", force: :cascade do |t| - t.integer "combo_choice_id", null: false - t.integer "answer_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["answer_id", "combo_choice_id"], name: "index_combo_choice_answers_on_answer_id_and_combo_choice_id", unique: true, using: :btree - t.index ["combo_choice_id"], name: "index_combo_choice_answers_on_combo_choice_id", using: :btree - end - - create_table "combo_choices", force: :cascade do |t| - t.integer "stem_id", null: false - t.decimal "correctness", precision: 3, scale: 2, default: "0.0", null: false - t.text "feedback" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["stem_id", "correctness"], name: "index_combo_choices_on_stem_id_and_correctness", using: :btree - end - - create_table "commontator_comments", force: :cascade do |t| - t.string "creator_type" - t.integer "creator_id" - t.string "editor_type" - t.integer "editor_id" - t.integer "thread_id", null: false - t.text "body", null: false + create_table "answers", id: :serial, force: :cascade do |t| + t.integer "question_id", null: false + t.text "content", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "sort_position", null: false + t.index ["question_id", "sort_position"], name: "index_answers_on_question_id_and_sort_position", unique: true + end + + create_table "attachments", id: :serial, force: :cascade do |t| + t.string "parent_type", null: false + t.integer "parent_id", null: false + t.string "asset", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["asset"], name: "index_attachments_on_asset" + t.index ["parent_id", "parent_type", "asset"], name: "index_attachments_on_parent_id_and_parent_type_and_asset", unique: true + end + + create_table "authors", id: :serial, force: :cascade do |t| + t.integer "sort_position", null: false + t.integer "publication_id", null: false + t.integer "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["publication_id", "sort_position"], name: "index_authors_on_publication_id_and_sort_position", unique: true + t.index ["user_id", "publication_id"], name: "index_authors_on_user_id_and_publication_id", unique: true + end + + create_table "class_licenses", id: :serial, force: :cascade do |t| + t.integer "sort_position", null: false + t.integer "license_id", null: false + t.string "class_name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["class_name", "sort_position"], name: "index_class_licenses_on_class_name_and_sort_position", unique: true + t.index ["license_id", "class_name"], name: "index_class_licenses_on_license_id_and_class_name", unique: true + end + + create_table "collaborator_solutions", id: :serial, force: :cascade do |t| + t.integer "question_id", null: false + t.string "title" + t.text "solution_type", null: false + t.text "content", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["question_id"], name: "index_collaborator_solutions_on_question_id" + t.index ["solution_type"], name: "index_collaborator_solutions_on_solution_type" + t.index ["title"], name: "index_collaborator_solutions_on_title" + end + + create_table "combo_choice_answers", id: :serial, force: :cascade do |t| + t.integer "combo_choice_id", null: false + t.integer "answer_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["answer_id", "combo_choice_id"], name: "index_combo_choice_answers_on_answer_id_and_combo_choice_id", unique: true + t.index ["combo_choice_id"], name: "index_combo_choice_answers_on_combo_choice_id" + end + + create_table "combo_choices", id: :serial, force: :cascade do |t| + t.integer "stem_id", null: false + t.decimal "correctness", precision: 3, scale: 2, default: "0.0", null: false + t.text "feedback" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["stem_id", "correctness"], name: "index_combo_choices_on_stem_id_and_correctness" + end + + create_table "commontator_comments", id: :serial, force: :cascade do |t| + t.string "creator_type" + t.integer "creator_id" + t.string "editor_type" + t.integer "editor_id" + t.integer "thread_id", null: false + t.text "body", null: false t.datetime "deleted_at" - t.integer "cached_votes_up", default: 0 - t.integer "cached_votes_down", default: 0 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["cached_votes_down"], name: "index_commontator_comments_on_cached_votes_down", using: :btree - t.index ["cached_votes_up"], name: "index_commontator_comments_on_cached_votes_up", using: :btree - t.index ["creator_id", "creator_type", "thread_id"], name: "index_commontator_comments_on_c_id_and_c_type_and_t_id", using: :btree - t.index ["thread_id", "created_at"], name: "index_commontator_comments_on_thread_id_and_created_at", using: :btree - end - - create_table "commontator_subscriptions", force: :cascade do |t| - t.string "subscriber_type", null: false - t.integer "subscriber_id", null: false - t.integer "thread_id", null: false + t.integer "cached_votes_up", default: 0 + t.integer "cached_votes_down", default: 0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["cached_votes_down"], name: "index_commontator_comments_on_cached_votes_down" + t.index ["cached_votes_up"], name: "index_commontator_comments_on_cached_votes_up" + t.index ["creator_id", "creator_type", "thread_id"], name: "index_commontator_comments_on_c_id_and_c_type_and_t_id" + t.index ["thread_id", "created_at"], name: "index_commontator_comments_on_thread_id_and_created_at" + end + + create_table "commontator_subscriptions", id: :serial, force: :cascade do |t| + t.string "subscriber_type", null: false + t.integer "subscriber_id", null: false + t.integer "thread_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.index ["subscriber_id", "subscriber_type", "thread_id"], name: "index_commontator_subscriptions_on_s_id_and_s_type_and_t_id", unique: true, using: :btree - t.index ["thread_id"], name: "index_commontator_subscriptions_on_thread_id", using: :btree + t.index ["subscriber_id", "subscriber_type", "thread_id"], name: "index_commontator_subscriptions_on_s_id_and_s_type_and_t_id", unique: true + t.index ["thread_id"], name: "index_commontator_subscriptions_on_thread_id" end - create_table "commontator_threads", force: :cascade do |t| - t.string "commontable_type" - t.integer "commontable_id" + create_table "commontator_threads", id: :serial, force: :cascade do |t| + t.string "commontable_type" + t.integer "commontable_id" t.datetime "closed_at" - t.string "closer_type" - t.integer "closer_id" + t.string "closer_type" + t.integer "closer_id" t.datetime "created_at" t.datetime "updated_at" - t.index ["commontable_id", "commontable_type"], name: "index_commontator_threads_on_c_id_and_c_type", unique: true, using: :btree - end - - create_table "community_solutions", force: :cascade do |t| - t.integer "question_id", null: false - t.string "title" - t.text "solution_type", null: false - t.text "content", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["question_id"], name: "index_community_solutions_on_question_id", using: :btree - t.index ["solution_type"], name: "index_community_solutions_on_solution_type", using: :btree - t.index ["title"], name: "index_community_solutions_on_title", using: :btree - end - - create_table "copyright_holders", force: :cascade do |t| - t.integer "sort_position", null: false - t.integer "publication_id", null: false - t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["publication_id", "sort_position"], name: "index_copyright_holders_on_publication_id_and_sort_position", unique: true, using: :btree - t.index ["user_id", "publication_id"], name: "index_copyright_holders_on_user_id_and_publication_id", unique: true, using: :btree - end - - create_table "deputizations", force: :cascade do |t| - t.integer "deputizer_id", null: false - t.integer "deputy_id", null: false - t.string "deputy_type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["deputizer_id"], name: "index_deputizations_on_deputizer_id", using: :btree - t.index ["deputy_id", "deputy_type", "deputizer_id"], name: "index_deputizations_on_d_id_and_d_type_and_d_id", unique: true, using: :btree - end - - create_table "derivations", force: :cascade do |t| - t.integer "sort_position", null: false - t.integer "derived_publication_id", null: false - t.integer "source_publication_id" - t.text "custom_attribution" - t.datetime "hidden_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["derived_publication_id", "hidden_at"], name: "index_derivations_on_derived_publication_id_and_hidden_at", using: :btree - t.index ["derived_publication_id", "sort_position"], name: "index_derivations_on_derived_publication_id_and_sort_position", unique: true, using: :btree - t.index ["source_publication_id", "derived_publication_id"], name: "index_derivations_on_source_p_id_and_derived_p_id", unique: true, using: :btree + t.index ["commontable_id", "commontable_type"], name: "index_commontator_threads_on_c_id_and_c_type", unique: true + end + + create_table "community_solutions", id: :serial, force: :cascade do |t| + t.integer "question_id", null: false + t.string "title" + t.text "solution_type", null: false + t.text "content", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["question_id"], name: "index_community_solutions_on_question_id" + t.index ["solution_type"], name: "index_community_solutions_on_solution_type" + t.index ["title"], name: "index_community_solutions_on_title" + end + + create_table "copyright_holders", id: :serial, force: :cascade do |t| + t.integer "sort_position", null: false + t.integer "publication_id", null: false + t.integer "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["publication_id", "sort_position"], name: "index_copyright_holders_on_publication_id_and_sort_position", unique: true + t.index ["user_id", "publication_id"], name: "index_copyright_holders_on_user_id_and_publication_id", unique: true end - create_table "exercise_tags", force: :cascade do |t| - t.integer "exercise_id", null: false - t.integer "tag_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["exercise_id", "tag_id"], name: "index_exercise_tags_on_exercise_id_and_tag_id", unique: true, using: :btree - t.index ["tag_id"], name: "index_exercise_tags_on_tag_id", using: :btree + create_table "deputizations", id: :serial, force: :cascade do |t| + t.integer "deputizer_id", null: false + t.string "deputy_type", null: false + t.integer "deputy_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["deputizer_id"], name: "index_deputizations_on_deputizer_id" + t.index ["deputy_id", "deputy_type", "deputizer_id"], name: "index_deputizations_on_d_id_and_d_type_and_d_id", unique: true + end + + create_table "derivations", id: :serial, force: :cascade do |t| + t.integer "sort_position", null: false + t.integer "derived_publication_id", null: false + t.integer "source_publication_id" + t.text "custom_attribution" + t.datetime "hidden_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["derived_publication_id", "hidden_at"], name: "index_derivations_on_derived_publication_id_and_hidden_at" + t.index ["derived_publication_id", "sort_position"], name: "index_derivations_on_derived_publication_id_and_sort_position", unique: true + t.index ["source_publication_id", "derived_publication_id"], name: "index_derivations_on_source_p_id_and_derived_p_id", unique: true end - create_table "exercises", force: :cascade do |t| - t.string "title" - t.text "stimulus" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "vocab_term_id" - t.string "a15k_identifier" - t.integer "a15k_version" - t.boolean "release_to_a15k" - t.index ["title"], name: "index_exercises_on_title", using: :btree - t.index ["vocab_term_id"], name: "index_exercises_on_vocab_term_id", using: :btree + create_table "exercise_tags", id: :serial, force: :cascade do |t| + t.integer "exercise_id", null: false + t.integer "tag_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["exercise_id", "tag_id"], name: "index_exercise_tags_on_exercise_id_and_tag_id", unique: true + t.index ["tag_id"], name: "index_exercise_tags_on_tag_id" end - create_table "fine_print_contracts", force: :cascade do |t| - t.string "name", null: false - t.integer "version" - t.string "title", null: false - t.text "content", null: false + create_table "exercises", id: :serial, force: :cascade do |t| + t.string "title" + t.text "stimulus" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "vocab_term_id" + t.string "a15k_identifier" + t.integer "a15k_version" + t.boolean "release_to_a15k" + t.index ["title"], name: "index_exercises_on_title" + t.index ["vocab_term_id"], name: "index_exercises_on_vocab_term_id" + end + + create_table "fine_print_contracts", id: :serial, force: :cascade do |t| + t.string "name", null: false + t.integer "version" + t.string "title", null: false + t.text "content", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["name", "version"], name: "index_fine_print_contracts_on_name_and_version", unique: true, using: :btree + t.index ["name", "version"], name: "index_fine_print_contracts_on_name_and_version", unique: true end - create_table "fine_print_signatures", force: :cascade do |t| - t.integer "contract_id", null: false - t.integer "user_id", null: false - t.string "user_type", null: false + create_table "fine_print_signatures", id: :serial, force: :cascade do |t| + t.integer "contract_id", null: false + t.string "user_type", null: false + t.integer "user_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.boolean "is_implicit", default: false, null: false - t.index ["contract_id"], name: "index_fine_print_signatures_on_contract_id", using: :btree - t.index ["user_id", "user_type", "contract_id"], name: "index_fine_print_signatures_on_u_id_and_u_type_and_c_id", unique: true, using: :btree - end - - create_table "hints", force: :cascade do |t| - t.integer "sort_position", null: false - t.integer "question_id", null: false - t.text "content", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["question_id", "sort_position"], name: "index_hints_on_question_id_and_sort_position", unique: true, using: :btree + t.boolean "is_implicit", default: false, null: false + t.index ["contract_id"], name: "index_fine_print_signatures_on_contract_id" + t.index ["user_id", "user_type", "contract_id"], name: "index_fine_print_signatures_on_u_id_and_u_type_and_c_id", unique: true end - create_table "license_compatibilities", force: :cascade do |t| - t.integer "original_license_id", null: false - t.integer "combined_license_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["combined_license_id", "original_license_id"], name: "index_license_compatibilities_on_c_l_id_and_o_l_id", unique: true, using: :btree - t.index ["original_license_id"], name: "index_license_compatibilities_on_original_license_id", using: :btree + create_table "hints", id: :serial, force: :cascade do |t| + t.integer "sort_position", null: false + t.integer "question_id", null: false + t.text "content", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["question_id", "sort_position"], name: "index_hints_on_question_id_and_sort_position", unique: true end - create_table "licenses", force: :cascade do |t| - t.string "name", null: false - t.string "title", null: false - t.string "url", null: false - t.text "publishing_contract", null: false - t.text "copyright_notice", null: false - t.boolean "requires_attribution", default: true, null: false - t.boolean "requires_share_alike", default: false, null: false - t.boolean "allows_derivatives", default: true, null: false - t.boolean "allows_commercial_use", default: true, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["name"], name: "index_licenses_on_name", unique: true, using: :btree - t.index ["title"], name: "index_licenses_on_title", unique: true, using: :btree - t.index ["url"], name: "index_licenses_on_url", unique: true, using: :btree + create_table "license_compatibilities", id: :serial, force: :cascade do |t| + t.integer "original_license_id", null: false + t.integer "combined_license_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["combined_license_id", "original_license_id"], name: "index_license_compatibilities_on_c_l_id_and_o_l_id", unique: true + t.index ["original_license_id"], name: "index_license_compatibilities_on_original_license_id" + end + + create_table "licenses", id: :serial, force: :cascade do |t| + t.string "name", null: false + t.string "title", null: false + t.string "url", null: false + t.text "publishing_contract", null: false + t.text "copyright_notice", null: false + t.boolean "requires_attribution", default: true, null: false + t.boolean "requires_share_alike", default: false, null: false + t.boolean "allows_derivatives", default: true, null: false + t.boolean "allows_commercial_use", default: true, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_licenses_on_name", unique: true + t.index ["title"], name: "index_licenses_on_title", unique: true + t.index ["url"], name: "index_licenses_on_url", unique: true end - create_table "list_editors", force: :cascade do |t| - t.integer "editor_id", null: false - t.string "editor_type", null: false - t.integer "list_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["editor_id", "editor_type", "list_id"], name: "index_list_editors_on_editor_id_and_editor_type_and_list_id", unique: true, using: :btree - t.index ["list_id"], name: "index_list_editors_on_list_id", using: :btree + create_table "list_editors", id: :serial, force: :cascade do |t| + t.string "editor_type", null: false + t.integer "editor_id", null: false + t.integer "list_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["editor_id", "editor_type", "list_id"], name: "index_list_editors_on_editor_id_and_editor_type_and_list_id", unique: true + t.index ["list_id"], name: "index_list_editors_on_list_id" end - create_table "list_nestings", force: :cascade do |t| - t.integer "parent_list_id", null: false - t.integer "child_list_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["child_list_id"], name: "index_list_nestings_on_child_list_id", unique: true, using: :btree - t.index ["parent_list_id"], name: "index_list_nestings_on_parent_list_id", using: :btree + create_table "list_nestings", id: :serial, force: :cascade do |t| + t.integer "parent_list_id", null: false + t.integer "child_list_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["child_list_id"], name: "index_list_nestings_on_child_list_id", unique: true + t.index ["parent_list_id"], name: "index_list_nestings_on_parent_list_id" end - create_table "list_owners", force: :cascade do |t| - t.integer "owner_id", null: false - t.string "owner_type", null: false - t.integer "list_id", null: false + create_table "list_owners", id: :serial, force: :cascade do |t| + t.string "owner_type", null: false + t.integer "owner_id", null: false + t.integer "list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["list_id"], name: "index_list_owners_on_list_id", using: :btree - t.index ["owner_id", "owner_type", "list_id"], name: "index_list_owners_on_owner_id_and_owner_type_and_list_id", unique: true, using: :btree + t.index ["list_id"], name: "index_list_owners_on_list_id" + t.index ["owner_id", "owner_type", "list_id"], name: "index_list_owners_on_owner_id_and_owner_type_and_list_id", unique: true end - create_table "list_publication_groups", force: :cascade do |t| - t.integer "sort_position", null: false - t.integer "list_id", null: false - t.integer "publication_group_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["list_id", "sort_position"], name: "index_list_publication_groups_on_list_id_and_sort_position", unique: true, using: :btree - t.index ["publication_group_id", "list_id"], name: "index_list_publication_groups_on_p_g_id_and_l_id", unique: true, using: :btree + create_table "list_publication_groups", id: :serial, force: :cascade do |t| + t.integer "sort_position", null: false + t.integer "list_id", null: false + t.integer "publication_group_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["list_id", "sort_position"], name: "index_list_publication_groups_on_list_id_and_sort_position", unique: true + t.index ["publication_group_id", "list_id"], name: "index_list_publication_groups_on_p_g_id_and_l_id", unique: true end - create_table "list_readers", force: :cascade do |t| - t.integer "reader_id", null: false - t.string "reader_type", null: false - t.integer "list_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["list_id"], name: "index_list_readers_on_list_id", using: :btree - t.index ["reader_id", "reader_type", "list_id"], name: "index_list_readers_on_reader_id_and_reader_type_and_list_id", unique: true, using: :btree + create_table "list_readers", id: :serial, force: :cascade do |t| + t.string "reader_type", null: false + t.integer "reader_id", null: false + t.integer "list_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["list_id"], name: "index_list_readers_on_list_id" + t.index ["reader_id", "reader_type", "list_id"], name: "index_list_readers_on_reader_id_and_reader_type_and_list_id", unique: true end - create_table "lists", force: :cascade do |t| - t.string "name", null: false + create_table "lists", id: :serial, force: :cascade do |t| + t.string "name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["name"], name: "index_lists_on_name", using: :btree + t.index ["name"], name: "index_lists_on_name" end - create_table "logic_variable_values", force: :cascade do |t| - t.integer "logic_variable_id", null: false - t.integer "seed", null: false - t.text "value", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["logic_variable_id", "seed"], name: "index_logic_variable_values_on_logic_variable_id_and_seed", unique: true, using: :btree + create_table "logic_variable_values", id: :serial, force: :cascade do |t| + t.integer "logic_variable_id", null: false + t.integer "seed", null: false + t.text "value", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["logic_variable_id", "seed"], name: "index_logic_variable_values_on_logic_variable_id_and_seed", unique: true end - create_table "logic_variables", force: :cascade do |t| - t.integer "logic_id", null: false - t.string "variable", null: false + create_table "logic_variables", id: :serial, force: :cascade do |t| + t.integer "logic_id", null: false + t.string "variable", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.index ["logic_id", "variable"], name: "index_logic_variables_on_logic_id_and_variable", unique: true, using: :btree + t.index ["logic_id", "variable"], name: "index_logic_variables_on_logic_id_and_variable", unique: true end - create_table "logics", force: :cascade do |t| - t.integer "parent_id", null: false - t.string "parent_type", null: false - t.string "language", null: false - t.text "code", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["parent_id", "parent_type", "language"], name: "index_logics_on_parent_id_and_parent_type_and_language", unique: true, using: :btree + create_table "logics", id: :serial, force: :cascade do |t| + t.string "parent_type", null: false + t.integer "parent_id", null: false + t.string "language", null: false + t.text "code", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["parent_id", "parent_type", "language"], name: "index_logics_on_parent_id_and_parent_type_and_language", unique: true end - create_table "oauth_access_grants", force: :cascade do |t| - t.integer "resource_owner_id", null: false - t.integer "application_id", null: false - t.string "token", null: false - t.integer "expires_in", null: false - t.text "redirect_uri", null: false - t.datetime "created_at", null: false + create_table "oauth_access_grants", id: :serial, force: :cascade do |t| + t.integer "resource_owner_id", null: false + t.integer "application_id", null: false + t.string "token", null: false + t.integer "expires_in", null: false + t.text "redirect_uri", null: false + t.datetime "created_at", null: false t.datetime "revoked_at" - t.string "scopes" - t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree + t.string "scopes" + t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true end - create_table "oauth_access_tokens", force: :cascade do |t| - t.integer "resource_owner_id" - t.integer "application_id" - t.string "token", null: false - t.string "refresh_token" - t.integer "expires_in" + create_table "oauth_access_tokens", id: :serial, force: :cascade do |t| + t.integer "resource_owner_id" + t.integer "application_id" + t.string "token", null: false + t.string "refresh_token" + t.integer "expires_in" t.datetime "revoked_at" - t.datetime "created_at", null: false - t.string "scopes" - t.string "previous_refresh_token", default: "", null: false - t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree - t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree - t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree - end - - create_table "oauth_applications", force: :cascade do |t| - t.string "name", null: false - t.string "uid", null: false - t.string "secret", null: false - t.text "redirect_uri", null: false - t.string "scopes", default: "", null: false + t.datetime "created_at", null: false + t.string "scopes" + t.string "previous_refresh_token", default: "", null: false + t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true + t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id" + t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true + end + + create_table "oauth_applications", id: :serial, force: :cascade do |t| + t.string "name", null: false + t.string "uid", null: false + t.string "secret", null: false + t.text "redirect_uri", null: false + t.string "scopes", default: "", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "owner_id" - t.string "owner_type" - t.boolean "confidential", default: true, null: false - t.index ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree - t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree - end - - create_table "openstax_accounts_accounts", force: :cascade do |t| - t.integer "openstax_uid" - t.string "username" - t.string "access_token" - t.string "first_name" - t.string "last_name" - t.string "full_name" - t.string "title" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "faculty_status", default: 0, null: false - t.string "salesforce_contact_id" - t.uuid "uuid", default: -> { "gen_random_uuid()" } - t.integer "role", default: 0, null: false - t.citext "support_identifier" - t.boolean "is_test" - t.integer "school_type", default: 0, null: false - t.index ["access_token"], name: "index_openstax_accounts_accounts_on_access_token", unique: true, using: :btree - t.index ["faculty_status"], name: "index_openstax_accounts_accounts_on_faculty_status", using: :btree - t.index ["first_name"], name: "index_openstax_accounts_accounts_on_first_name", using: :btree - t.index ["full_name"], name: "index_openstax_accounts_accounts_on_full_name", using: :btree - t.index ["last_name"], name: "index_openstax_accounts_accounts_on_last_name", using: :btree - t.index ["openstax_uid"], name: "index_openstax_accounts_accounts_on_openstax_uid", unique: true, using: :btree - t.index ["role"], name: "index_openstax_accounts_accounts_on_role", using: :btree - t.index ["salesforce_contact_id"], name: "index_openstax_accounts_accounts_on_salesforce_contact_id", using: :btree - t.index ["school_type"], name: "index_openstax_accounts_accounts_on_school_type", using: :btree - t.index ["support_identifier"], name: "index_openstax_accounts_accounts_on_support_identifier", unique: true, using: :btree - t.index ["username"], name: "index_openstax_accounts_accounts_on_username", unique: true, using: :btree - t.index ["uuid"], name: "index_openstax_accounts_accounts_on_uuid", unique: true, using: :btree - end - - create_table "openstax_accounts_group_members", force: :cascade do |t| - t.integer "group_id", null: false - t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_members_on_group_id_and_user_id", unique: true, using: :btree - t.index ["user_id"], name: "index_openstax_accounts_group_members_on_user_id", using: :btree - end - - create_table "openstax_accounts_group_nestings", force: :cascade do |t| - t.integer "member_group_id", null: false - t.integer "container_group_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["container_group_id"], name: "index_openstax_accounts_group_nestings_on_container_group_id", using: :btree - t.index ["member_group_id"], name: "index_openstax_accounts_group_nestings_on_member_group_id", unique: true, using: :btree - end - - create_table "openstax_accounts_group_owners", force: :cascade do |t| - t.integer "group_id", null: false - t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_owners_on_group_id_and_user_id", unique: true, using: :btree - t.index ["user_id"], name: "index_openstax_accounts_group_owners_on_user_id", using: :btree - end - - create_table "openstax_accounts_groups", force: :cascade do |t| - t.integer "openstax_uid", null: false - t.boolean "is_public", default: false, null: false - t.string "name" - t.text "cached_subtree_group_ids" - t.text "cached_supertree_group_ids" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["is_public"], name: "index_openstax_accounts_groups_on_is_public", using: :btree - t.index ["openstax_uid"], name: "index_openstax_accounts_groups_on_openstax_uid", unique: true, using: :btree - end - - create_table "publication_groups", force: :cascade do |t| - t.string "publishable_type", null: false - t.integer "number", null: false - t.uuid "uuid", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "latest_version", null: false - t.integer "latest_published_version" - t.string "nickname" - t.index ["id", "latest_published_version"], name: "index_publication_groups_on_id_and_latest_published_version", using: :btree - t.index ["id", "latest_version"], name: "index_publication_groups_on_id_and_latest_version", using: :btree - t.index ["nickname"], name: "index_publication_groups_on_nickname", unique: true, using: :btree - t.index ["number", "publishable_type"], name: "index_publication_groups_on_number_and_publishable_type", unique: true, using: :btree - t.index ["publishable_type"], name: "index_publication_groups_on_publishable_type", using: :btree - t.index ["uuid"], name: "index_publication_groups_on_uuid", unique: true, using: :btree - end - - create_table "publications", force: :cascade do |t| - t.integer "publishable_id", null: false - t.string "publishable_type", null: false - t.integer "license_id" - t.integer "version", null: false + t.integer "owner_id" + t.string "owner_type" + t.boolean "confidential", default: true, null: false + t.index ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type" + t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true + end + + create_table "openstax_accounts_accounts", id: :serial, force: :cascade do |t| + t.integer "openstax_uid" + t.string "username" + t.string "access_token" + t.string "first_name" + t.string "last_name" + t.string "full_name" + t.string "title" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "faculty_status", default: 0, null: false + t.string "salesforce_contact_id" + t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false + t.integer "role", default: 0, null: false + t.citext "support_identifier" + t.boolean "is_test" + t.integer "school_type", default: 0, null: false + t.index ["access_token"], name: "index_openstax_accounts_accounts_on_access_token", unique: true + t.index ["faculty_status"], name: "index_openstax_accounts_accounts_on_faculty_status" + t.index ["first_name"], name: "index_openstax_accounts_accounts_on_first_name" + t.index ["full_name"], name: "index_openstax_accounts_accounts_on_full_name" + t.index ["last_name"], name: "index_openstax_accounts_accounts_on_last_name" + t.index ["openstax_uid"], name: "index_openstax_accounts_accounts_on_openstax_uid", unique: true + t.index ["role"], name: "index_openstax_accounts_accounts_on_role" + t.index ["salesforce_contact_id"], name: "index_openstax_accounts_accounts_on_salesforce_contact_id" + t.index ["school_type"], name: "index_openstax_accounts_accounts_on_school_type" + t.index ["support_identifier"], name: "index_openstax_accounts_accounts_on_support_identifier", unique: true + t.index ["username"], name: "index_openstax_accounts_accounts_on_username", unique: true + t.index ["uuid"], name: "index_openstax_accounts_accounts_on_uuid", unique: true + end + + create_table "openstax_accounts_group_members", id: :serial, force: :cascade do |t| + t.integer "group_id", null: false + t.integer "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_members_on_group_id_and_user_id", unique: true + t.index ["user_id"], name: "index_openstax_accounts_group_members_on_user_id" + end + + create_table "openstax_accounts_group_nestings", id: :serial, force: :cascade do |t| + t.integer "member_group_id", null: false + t.integer "container_group_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["container_group_id"], name: "index_openstax_accounts_group_nestings_on_container_group_id" + t.index ["member_group_id"], name: "index_openstax_accounts_group_nestings_on_member_group_id", unique: true + end + + create_table "openstax_accounts_group_owners", id: :serial, force: :cascade do |t| + t.integer "group_id", null: false + t.integer "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["group_id", "user_id"], name: "index_openstax_accounts_group_owners_on_group_id_and_user_id", unique: true + t.index ["user_id"], name: "index_openstax_accounts_group_owners_on_user_id" + end + + create_table "openstax_accounts_groups", id: :serial, force: :cascade do |t| + t.integer "openstax_uid", null: false + t.boolean "is_public", default: false, null: false + t.string "name" + t.text "cached_subtree_group_ids" + t.text "cached_supertree_group_ids" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["is_public"], name: "index_openstax_accounts_groups_on_is_public" + t.index ["openstax_uid"], name: "index_openstax_accounts_groups_on_openstax_uid", unique: true + end + + create_table "publication_groups", id: :serial, force: :cascade do |t| + t.string "publishable_type", null: false + t.integer "number", null: false + t.uuid "uuid", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "latest_version", null: false + t.integer "latest_published_version" + t.string "nickname" + t.index ["id", "latest_published_version"], name: "index_publication_groups_on_id_and_latest_published_version" + t.index ["id", "latest_version"], name: "index_publication_groups_on_id_and_latest_version" + t.index ["nickname"], name: "index_publication_groups_on_nickname", unique: true + t.index ["number", "publishable_type"], name: "index_publication_groups_on_number_and_publishable_type", unique: true + t.index ["publishable_type"], name: "index_publication_groups_on_publishable_type" + t.index ["uuid"], name: "index_publication_groups_on_uuid", unique: true + end + + create_table "publications", id: :serial, force: :cascade do |t| + t.string "publishable_type", null: false + t.integer "publishable_id", null: false + t.integer "license_id" + t.integer "version", null: false t.datetime "published_at" t.datetime "yanked_at" t.datetime "embargoed_until" - t.boolean "embargo_children_only", default: false, null: false - t.boolean "major_change", default: false, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "publication_group_id", null: false - t.uuid "uuid", null: false - t.index ["embargoed_until"], name: "index_publications_on_embargoed_until", using: :btree - t.index ["license_id"], name: "index_publications_on_license_id", using: :btree - t.index ["publication_group_id", "version"], name: "index_publications_on_publication_group_id_and_version", using: :btree - t.index ["publishable_id", "publishable_type"], name: "index_publications_on_publishable_id_and_publishable_type", unique: true, using: :btree - t.index ["published_at"], name: "index_publications_on_published_at", using: :btree - t.index ["uuid"], name: "index_publications_on_uuid", unique: true, using: :btree - t.index ["yanked_at"], name: "index_publications_on_yanked_at", using: :btree - end - - create_table "question_dependencies", force: :cascade do |t| - t.integer "parent_question_id", null: false - t.integer "dependent_question_id", null: false - t.boolean "is_optional", default: false, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["dependent_question_id", "parent_question_id"], name: "index_question_dependencies_on_dependent_q_id_and_parent_q_id", unique: true, using: :btree - t.index ["parent_question_id"], name: "index_question_dependencies_on_parent_question_id", using: :btree - end - - create_table "questions", force: :cascade do |t| - t.integer "exercise_id", null: false - t.text "stimulus" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.boolean "answer_order_matters", default: false, null: false - t.integer "sort_position", null: false - t.index ["exercise_id", "sort_position"], name: "index_questions_on_exercise_id_and_sort_position", unique: true, using: :btree - end - - create_table "stem_answers", force: :cascade do |t| - t.integer "stem_id", null: false - t.integer "answer_id", null: false - t.decimal "correctness", precision: 3, scale: 2, default: "0.0", null: false - t.text "feedback" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["answer_id", "stem_id"], name: "index_stem_answers_on_answer_id_and_stem_id", unique: true, using: :btree - t.index ["stem_id", "correctness"], name: "index_stem_answers_on_stem_id_and_correctness", using: :btree - end - - create_table "stems", force: :cascade do |t| - t.integer "question_id", null: false - t.text "content", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["question_id"], name: "index_stems_on_question_id", using: :btree - end - - create_table "stylings", force: :cascade do |t| - t.integer "stylable_id", null: false - t.string "stylable_type", null: false - t.string "style", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["stylable_id", "stylable_type", "style"], name: "index_stylings_on_stylable_id_and_stylable_type_and_style", unique: true, using: :btree - end - - create_table "tags", force: :cascade do |t| - t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["name"], name: "index_tags_on_name", unique: true, using: :btree - end - - create_table "trusted_applications", force: :cascade do |t| - t.integer "application_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["application_id"], name: "index_trusted_applications_on_application_id", unique: true, using: :btree - end - - create_table "users", force: :cascade do |t| - t.integer "account_id", null: false + t.boolean "embargo_children_only", default: false, null: false + t.boolean "major_change", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "publication_group_id", null: false + t.uuid "uuid", null: false + t.index ["embargoed_until"], name: "index_publications_on_embargoed_until" + t.index ["license_id"], name: "index_publications_on_license_id" + t.index ["publication_group_id", "version"], name: "index_publications_on_publication_group_id_and_version" + t.index ["publishable_id", "publishable_type"], name: "index_publications_on_publishable_id_and_publishable_type", unique: true + t.index ["published_at"], name: "index_publications_on_published_at" + t.index ["uuid"], name: "index_publications_on_uuid", unique: true + t.index ["yanked_at"], name: "index_publications_on_yanked_at" + end + + create_table "question_dependencies", id: :serial, force: :cascade do |t| + t.integer "parent_question_id", null: false + t.integer "dependent_question_id", null: false + t.boolean "is_optional", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["dependent_question_id", "parent_question_id"], name: "index_question_dependencies_on_dependent_q_id_and_parent_q_id", unique: true + t.index ["parent_question_id"], name: "index_question_dependencies_on_parent_question_id" + end + + create_table "questions", id: :serial, force: :cascade do |t| + t.integer "exercise_id", null: false + t.text "stimulus" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "answer_order_matters", default: false, null: false + t.integer "sort_position", null: false + t.index ["exercise_id", "sort_position"], name: "index_questions_on_exercise_id_and_sort_position", unique: true + end + + create_table "stem_answers", id: :serial, force: :cascade do |t| + t.integer "stem_id", null: false + t.integer "answer_id", null: false + t.decimal "correctness", precision: 3, scale: 2, default: "0.0", null: false + t.text "feedback" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["answer_id", "stem_id"], name: "index_stem_answers_on_answer_id_and_stem_id", unique: true + t.index ["stem_id", "correctness"], name: "index_stem_answers_on_stem_id_and_correctness" + end + + create_table "stems", id: :serial, force: :cascade do |t| + t.integer "question_id", null: false + t.text "content", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["question_id"], name: "index_stems_on_question_id" + end + + create_table "stylings", id: :serial, force: :cascade do |t| + t.string "stylable_type", null: false + t.integer "stylable_id", null: false + t.string "style", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["stylable_id", "stylable_type", "style"], name: "index_stylings_on_stylable_id_and_stylable_type_and_style", unique: true + end + + create_table "tags", id: :serial, force: :cascade do |t| + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_tags_on_name", unique: true + end + + create_table "trusted_applications", id: :serial, force: :cascade do |t| + t.integer "application_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["application_id"], name: "index_trusted_applications_on_application_id", unique: true + end + + create_table "users", id: :serial, force: :cascade do |t| + t.integer "account_id", null: false t.datetime "deleted_at" - t.boolean "show_public_domain_attribution", default: true, null: false - t.boolean "forward_notifications_to_deputies", default: false, null: false - t.boolean "receive_role_notifications", default: true, null: false - t.boolean "receive_access_notifications", default: true, null: false - t.boolean "receive_comment_notifications", default: true, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["account_id"], name: "index_users_on_account_id", unique: true, using: :btree - t.index ["deleted_at"], name: "index_users_on_deleted_at", using: :btree - end - - create_table "vocab_distractors", force: :cascade do |t| - t.integer "vocab_term_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "distractor_publication_group_id", null: false - t.index ["distractor_publication_group_id"], name: "index_vocab_distractors_on_distractor_publication_group_id", using: :btree - t.index ["vocab_term_id", "distractor_publication_group_id"], name: "index_vocab_distractors_on_v_t_id_and_d_p_g_id", unique: true, using: :btree - end - - create_table "vocab_term_tags", force: :cascade do |t| - t.integer "vocab_term_id" - t.integer "tag_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["tag_id"], name: "index_vocab_term_tags_on_tag_id", using: :btree - t.index ["vocab_term_id", "tag_id"], name: "index_vocab_term_tags_on_vocab_term_id_and_tag_id", unique: true, using: :btree - end - - create_table "vocab_terms", force: :cascade do |t| - t.string "name", null: false - t.string "definition", default: "", null: false - t.string "distractor_literals", default: [], null: false, array: true - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["definition"], name: "index_vocab_terms_on_definition", using: :btree - t.index ["name", "definition"], name: "index_vocab_terms_on_name_and_definition", using: :btree - end - - create_table "votes", force: :cascade do |t| - t.integer "votable_id" - t.string "votable_type" - t.integer "voter_id" - t.string "voter_type" - t.boolean "vote_flag" - t.string "vote_scope" - t.integer "vote_weight" + t.boolean "show_public_domain_attribution", default: true, null: false + t.boolean "forward_notifications_to_deputies", default: false, null: false + t.boolean "receive_role_notifications", default: true, null: false + t.boolean "receive_access_notifications", default: true, null: false + t.boolean "receive_comment_notifications", default: true, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["account_id"], name: "index_users_on_account_id", unique: true + t.index ["deleted_at"], name: "index_users_on_deleted_at" + end + + create_table "vocab_distractors", id: :serial, force: :cascade do |t| + t.integer "vocab_term_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "distractor_publication_group_id", null: false + t.index ["distractor_publication_group_id"], name: "index_vocab_distractors_on_distractor_publication_group_id" + t.index ["vocab_term_id", "distractor_publication_group_id"], name: "index_vocab_distractors_on_v_t_id_and_d_p_g_id", unique: true + end + + create_table "vocab_term_tags", id: :serial, force: :cascade do |t| + t.integer "vocab_term_id" + t.integer "tag_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["tag_id"], name: "index_vocab_term_tags_on_tag_id" + t.index ["vocab_term_id", "tag_id"], name: "index_vocab_term_tags_on_vocab_term_id_and_tag_id", unique: true + end + + create_table "vocab_terms", id: :serial, force: :cascade do |t| + t.string "name", null: false + t.string "definition", default: "", null: false + t.string "distractor_literals", default: [], null: false, array: true + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["definition"], name: "index_vocab_terms_on_definition" + t.index ["name", "definition"], name: "index_vocab_terms_on_name_and_definition" + end + + create_table "votes", id: :serial, force: :cascade do |t| + t.string "votable_type" + t.integer "votable_id" + t.string "voter_type" + t.integer "voter_id" + t.boolean "vote_flag" + t.string "vote_scope" + t.integer "vote_weight" t.datetime "created_at" t.datetime "updated_at" - t.index ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope", using: :btree - t.index ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree + t.index ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope" + t.index ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope" end add_foreign_key "exercise_tags", "exercises", on_update: :cascade, on_delete: :cascade From 2cf6dc57d479dd357bf2208d27c5d220d09d8c32 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 7 Jun 2019 14:19:43 -0500 Subject: [PATCH 38/50] 5.2 defaults and rails cache key change --- app/representers/api/v1/exercises/representer.rb | 2 +- .../term_with_distractors_and_exercise_ids_representer.rb | 2 +- config/application.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/representers/api/v1/exercises/representer.rb b/app/representers/api/v1/exercises/representer.rb index 61305cf4..6caedefd 100644 --- a/app/representers/api/v1/exercises/representer.rb +++ b/app/representers/api/v1/exercises/representer.rb @@ -67,7 +67,7 @@ def self.cache_key_types_for(represented, options = {}) end def self.cache_key_for(represented, type) - "#{represented.cache_key}/#{type}" + "#{represented.cache_key}/##{represented.cache_version}/#{type}" end def self.all_cache_keys_for(represented, options = {}) diff --git a/app/representers/api/v1/vocabs/term_with_distractors_and_exercise_ids_representer.rb b/app/representers/api/v1/vocabs/term_with_distractors_and_exercise_ids_representer.rb index 668946c8..bbbdcc03 100644 --- a/app/representers/api/v1/vocabs/term_with_distractors_and_exercise_ids_representer.rb +++ b/app/representers/api/v1/vocabs/term_with_distractors_and_exercise_ids_representer.rb @@ -53,7 +53,7 @@ def self.cache_key_types_for(represented, options = {}) end def self.cache_key_for(represented, type) - "#{represented.cache_key}/#{type}" + "#{represented.cache_key}/#{represented.cache_version}/#{type}" end def self.all_cache_keys_for(represented, options = {}) diff --git a/config/application.rb b/config/application.rb index 1e2ac054..6e962cea 100644 --- a/config/application.rb +++ b/config/application.rb @@ -12,7 +12,7 @@ module Exercises class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.1 + config.load_defaults 5.2 # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers From b431deab24939676af06bfcdf778d62eabb8833e Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 7 Jun 2019 14:20:28 -0500 Subject: [PATCH 39/50] force children to be saved w/ autosave: true --- app/models/publication.rb | 2 +- app/models/question.rb | 2 +- app/models/vocab_term.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/publication.rb b/app/models/publication.rb index d72ac7da..8471970c 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -1,7 +1,7 @@ class Publication < ApplicationRecord belongs_to :publication_group, inverse_of: :publications - belongs_to :publishable, polymorphic: true, inverse_of: :publication, touch: true + belongs_to :publishable, polymorphic: true, inverse_of: :publication, touch: true, autosave: true belongs_to :license, optional: true sortable_has_many :authors, dependent: :destroy, inverse_of: :publication diff --git a/app/models/question.rb b/app/models/question.rb index c0845960..de79ee4a 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -8,7 +8,7 @@ class Question < ApplicationRecord has_many :stems, dependent: :destroy - sortable_has_many :answers, dependent: :destroy, inverse_of: :question + sortable_has_many :answers, dependent: :destroy, inverse_of: :question, autosave: true has_many :collaborator_solutions, dependent: :destroy has_many :community_solutions, dependent: :destroy diff --git a/app/models/vocab_term.rb b/app/models/vocab_term.rb index a28fe476..22656d72 100644 --- a/app/models/vocab_term.rb +++ b/app/models/vocab_term.rb @@ -51,7 +51,7 @@ class VocabTerm < ApplicationRecord has_tags - has_many :vocab_distractors, dependent: :destroy + has_many :vocab_distractors, dependent: :destroy, autosave: true has_many :exercises, dependent: :destroy, autosave: true From 5400cfdfb73bb0bdcff36be385d1356d71a350d8 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 7 Jun 2019 14:39:49 -0500 Subject: [PATCH 40/50] do not autosave publishable --- app/models/publication.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/publication.rb b/app/models/publication.rb index 8471970c..d72ac7da 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -1,7 +1,7 @@ class Publication < ApplicationRecord belongs_to :publication_group, inverse_of: :publications - belongs_to :publishable, polymorphic: true, inverse_of: :publication, touch: true, autosave: true + belongs_to :publishable, polymorphic: true, inverse_of: :publication, touch: true belongs_to :license, optional: true sortable_has_many :authors, dependent: :destroy, inverse_of: :publication From 3674a4c0a307df40837143c6a135ba6b858f36a4 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 7 Jun 2019 14:46:39 -0500 Subject: [PATCH 41/50] reorder save for exercise and associated publication models --- app/controllers/api/v1/exercises_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/exercises_controller.rb b/app/controllers/api/v1/exercises_controller.rb index 4d4918a9..c9c1a32c 100644 --- a/app/controllers/api/v1/exercises_controller.rb +++ b/app/controllers/api/v1/exercises_controller.rb @@ -119,7 +119,7 @@ def create OSU::AccessPolicy.require_action_allowed!(:create, current_api_user, exercise) - if exercise.save && publication_group.save + if publication.save && publication_group.save && exercise.save respond_with exercise, create_options.merge(represent_with_options) else render_api_errors(publication_group.errors) || render_api_errors(exercise.errors) From 5c8d6fe89284ec5068a18709b3981ec8013801cf Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Fri, 7 Jun 2019 14:55:05 -0500 Subject: [PATCH 42/50] update schema - uuid-ossp extension needed? --- db/schema.rb | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index fd51d613..609daf5f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -16,6 +16,7 @@ enable_extension "citext" enable_extension "pgcrypto" enable_extension "plpgsql" + enable_extension "uuid-ossp" create_table "administrators", id: :serial, force: :cascade do |t| t.integer "user_id", null: false @@ -34,8 +35,8 @@ end create_table "attachments", id: :serial, force: :cascade do |t| - t.string "parent_type", null: false t.integer "parent_id", null: false + t.string "parent_type", null: false t.string "asset", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -156,8 +157,8 @@ create_table "deputizations", id: :serial, force: :cascade do |t| t.integer "deputizer_id", null: false - t.string "deputy_type", null: false t.integer "deputy_id", null: false + t.string "deputy_type", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["deputizer_id"], name: "index_deputizations_on_deputizer_id" @@ -211,8 +212,8 @@ create_table "fine_print_signatures", id: :serial, force: :cascade do |t| t.integer "contract_id", null: false - t.string "user_type", null: false t.integer "user_id", null: false + t.string "user_type", null: false t.datetime "created_at" t.datetime "updated_at" t.boolean "is_implicit", default: false, null: false @@ -256,8 +257,8 @@ end create_table "list_editors", id: :serial, force: :cascade do |t| - t.string "editor_type", null: false t.integer "editor_id", null: false + t.string "editor_type", null: false t.integer "list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -275,8 +276,8 @@ end create_table "list_owners", id: :serial, force: :cascade do |t| - t.string "owner_type", null: false t.integer "owner_id", null: false + t.string "owner_type", null: false t.integer "list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -295,8 +296,8 @@ end create_table "list_readers", id: :serial, force: :cascade do |t| - t.string "reader_type", null: false t.integer "reader_id", null: false + t.string "reader_type", null: false t.integer "list_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -329,8 +330,8 @@ end create_table "logics", id: :serial, force: :cascade do |t| - t.string "parent_type", null: false t.integer "parent_id", null: false + t.string "parent_type", null: false t.string "language", null: false t.text "code", null: false t.datetime "created_at", null: false @@ -468,8 +469,8 @@ end create_table "publications", id: :serial, force: :cascade do |t| - t.string "publishable_type", null: false t.integer "publishable_id", null: false + t.string "publishable_type", null: false t.integer "license_id" t.integer "version", null: false t.datetime "published_at" @@ -530,8 +531,8 @@ end create_table "stylings", id: :serial, force: :cascade do |t| - t.string "stylable_type", null: false t.integer "stylable_id", null: false + t.string "stylable_type", null: false t.string "style", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -595,10 +596,10 @@ end create_table "votes", id: :serial, force: :cascade do |t| - t.string "votable_type" t.integer "votable_id" - t.string "voter_type" + t.string "votable_type" t.integer "voter_id" + t.string "voter_type" t.boolean "vote_flag" t.string "vote_scope" t.integer "vote_weight" From ae55ecda970d2e78fcea291b95efebccec00934e Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:40:06 -0500 Subject: [PATCH 43/50] remove comments - unpin/upgrade pg gem --- Gemfile | 10 ++-------- Gemfile.lock | 6 +++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Gemfile b/Gemfile index 3356651d..7b82ab16 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ git_source(:github) do |repo_name| end # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 5.2' +gem 'rails', '~> 5.2.3' # Bootstrap gem 'bootstrap-sass' @@ -59,7 +59,6 @@ gem 'openstax_utilities' gem 'whenever' # Talks to Accounts (latest version is broken) -# gem 'omniauth-oauth2', '~> 1.3.1' gem 'omniauth-oauth2' # OpenStax Accounts integration @@ -93,7 +92,6 @@ gem 'mimemagic' gem 'mini_magick' # Markdown parsing -# Pinned for Rails 4.X gem 'kramdown' # Read Excel xlsx spreadsheet files @@ -121,8 +119,7 @@ gem 'acts_as_votable' gem 'scout_apm', '~> 3.0.x' # PostgreSQL database -# Pinned for rails 4.X -gem 'pg', '~> 0.18' +gem 'pg' # HTTP requests gem 'httparty' @@ -181,14 +178,11 @@ group :development, :test do gem 'rspec-rails' # Mute asset pipeline log messages -# gem 'quiet_assets' # Fixture replacement - # Pinned for rails 4.X gem 'factory_bot_rails' # Lorem Ipsum - # Pinned to avoid 18n problem gem 'faker' # Database cleaning functionality for tests diff --git a/Gemfile.lock b/Gemfile.lock index b69b8131..0a3a9daa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -304,7 +304,7 @@ GEM parallel parser (2.6.3.0) ast (~> 2.4.0) - pg (0.21.0) + pg (1.1.4) public_suffix (3.1.0) rack (2.0.7) rack-test (1.1.0) @@ -556,9 +556,9 @@ DEPENDENCIES openstax_rescue_from openstax_utilities parallel_tests - pg (~> 0.18) + pg railroady - rails (~> 5.2) + rails (~> 5.2.3) rails-controller-testing rails-erd rails-html-sanitizer From ed145b90845344a79c9d756bbc233ef04c2a6849 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:41:50 -0500 Subject: [PATCH 44/50] cover all error cases --- app/controllers/api/v1/exercises_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v1/exercises_controller.rb b/app/controllers/api/v1/exercises_controller.rb index c9c1a32c..2cc1334a 100644 --- a/app/controllers/api/v1/exercises_controller.rb +++ b/app/controllers/api/v1/exercises_controller.rb @@ -122,7 +122,9 @@ def create if publication.save && publication_group.save && exercise.save respond_with exercise, create_options.merge(represent_with_options) else - render_api_errors(publication_group.errors) || render_api_errors(exercise.errors) + render_api_errors(publication.errors) || + render_api_errors(publication_group.errors) || + render_api_errors(exercise.errors) raise ActiveRecord::Rollback end end From adfac93af23b89792cc4362306c403c125c3c455 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:42:26 -0500 Subject: [PATCH 45/50] Don't use arel unless we need to --- app/models/attachment.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/attachment.rb b/app/models/attachment.rb index d2540ff1..9003a520 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -21,8 +21,7 @@ def remove_asset! def unique_asset return if asset.nil? || parent.nil? - at = Attachment.arel_table - return unless Attachment.where(at[:id].not_eq(id).and(at[:parent_id].eq(parent.id)).and(at[:asset].eq(asset.identifier))).exists? + return unless Attachment.where.not(id: id).where({parent_id: parent.id, asset: asset.identifier}).exists? errors.add(:asset, 'has already been associated with this resource') throw(:abort) end From 780411efcf2fad978991571f9e6909b8a02f18eb Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:43:43 -0500 Subject: [PATCH 46/50] delete double version scope --- ...20_add_school_type_to_accounts_accounts.openstax_accounts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb b/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb index 6d855405..1c042203 100644 --- a/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb +++ b/db/migrate/20190517204620_add_school_type_to_accounts_accounts.openstax_accounts.rb @@ -1,5 +1,5 @@ # This migration comes from openstax_accounts (originally 13) -class AddSchoolTypeToAccountsAccounts < ActiveRecord::Migration[4.2][4.2] +class AddSchoolTypeToAccountsAccounts < ActiveRecord::Migration[4.2] def change add_column :openstax_accounts_accounts, :school_type, :integer, null: false, default: 0 add_index :openstax_accounts_accounts, :school_type From 821036d968dbfa727caed0d319821593af60f6c2 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:44:28 -0500 Subject: [PATCH 47/50] whitespace --- app/models/publication.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/publication.rb b/app/models/publication.rb index d72ac7da..3c4dbfe5 100644 --- a/app/models/publication.rb +++ b/app/models/publication.rb @@ -44,13 +44,13 @@ class Publication < ApplicationRecord wheres = pubg[:uuid].eq(nn).or(pubg[:number].eq(nn)) case vv when NilClass - wheres = wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) + wheres = wheres.or(pub[:uuid].eq(nn)).and(pub[:published_at].not_eq(nil)) when 'draft', 'd' - wheres = wheres.and(pub[:published_at].eq(nil)) + wheres = wheres.and(pub[:published_at].eq(nil)) when 'latest' wheres else - wheres = wheres.and(pub[:version].eq(vv)) + wheres = wheres.and(pub[:version].eq(vv)) end joins(publication: :publication_group).where(wheres From ffcd6dddff19312fdca3ddd3501cd913a1e0860c Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:44:48 -0500 Subject: [PATCH 48/50] extraneous # --- app/representers/api/v1/exercises/representer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/representers/api/v1/exercises/representer.rb b/app/representers/api/v1/exercises/representer.rb index 6caedefd..20e3ceb3 100644 --- a/app/representers/api/v1/exercises/representer.rb +++ b/app/representers/api/v1/exercises/representer.rb @@ -67,7 +67,7 @@ def self.cache_key_types_for(represented, options = {}) end def self.cache_key_for(represented, type) - "#{represented.cache_key}/##{represented.cache_version}/#{type}" + "#{represented.cache_key}/#{represented.cache_version}/#{type}" end def self.all_cache_keys_for(represented, options = {}) From c63078d64b3b39017a6e76fdde4924bd8ee66a29 Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:45:59 -0500 Subject: [PATCH 49/50] last bits of arel_table cleanup - move vars up scope, catch space potential bug --- .../exercises/import/old/row_importer.rb | 6 +-- app/routines/search_exercises.rb | 39 ++++++++----------- app/routines/search_vocab_terms.rb | 35 +++++++---------- 3 files changed, 35 insertions(+), 45 deletions(-) diff --git a/app/routines/exercises/import/old/row_importer.rb b/app/routines/exercises/import/old/row_importer.rb index 030d9662..b9c4d675 100644 --- a/app/routines/exercises/import/old/row_importer.rb +++ b/app/routines/exercises/import/old/row_importer.rb @@ -72,9 +72,9 @@ def perform_row_import(row, index) pub = Publication.arel_table pubg = PublicationGroup.arel_table - latest_exercise = Exercise.joins([{publication: :publication_group}, {exercise_tags: :tag}]).where(exercise_tags: {tag: {name: exercise_id_tag}}).order ([pubg[:number].desc, pub[:version].desc]).first + latest_exercise = Exercise.joins([{publication: :publication_group}, {exercise_tags: :tag}]).where(exercise_tags: {tag: {name: exercise_id_tag}}).order([pubg[:number].desc, pub[:version].desc]).first - unless latest_exercise.empty? + unless latest_exercise.nil? ex.publication.publication_group = latest_exercise.publication.publication_group ex.publication.version = latest_exercise.publication.version + 1 end @@ -172,7 +172,7 @@ def perform_row_import(row, index) row = "Imported row ##{index + 1}" uid = skipped ? "Existing uid: #{latest_exercise.uid}" : "New uid: #{ex.uid}" changes = skipped ? "Exercise skipped (no changes)" : \ - "New #{latest_exercise.empty? ? 'exercise' : 'version'}" + "New #{latest_exercise.nil? ? 'exercise' : 'version'}" Rails.logger.info "#{row} - #{uid} - #{changes}" end diff --git a/app/routines/search_exercises.rb b/app/routines/search_exercises.rb index 4fd62d96..f76e82b4 100644 --- a/app/routines/search_exercises.rb +++ b/app/routines/search_exercises.rb @@ -32,14 +32,20 @@ def exec(params = {}, options = {}) # this "latest_visible" condition is disabled. latest_visible = true + ex = Exercise.arel_table + qu = Question.arel_table + st = Stem.arel_table + ans = Answer.arel_table + pub = Publication.arel_table + pubg = PublicationGroup.arel_table + acct = OpenStax::Accounts::Account.arel_table + # NB encapsulates magic knowledge of how ActiveRecord will alias second join + acct_author = OpenStax::Accounts::Account.arel_table + acct_copyright = OpenStax::Accounts::Account.arel_table.alias('accounts_users') + run(:search, relation: relation, sortable_fields: SORTABLE_FIELDS, params: params) do |with| with.default_keyword :content - - ex = Exercise.arel_table - qu = Question.arel_table - st = Stem.arel_table - ans = Answer.arel_table - + with.keyword :id do |ids| ids.each do |id| sanitized_ids = to_number_array(id) @@ -66,10 +72,6 @@ def exec(params = {}, options = {}) elsif sanitized_versions.empty? @items = @items.where(publication_groups: { number: sanitized_numbers }) else - # Combine the id's one at a time using Squeel - pub = Publication.arel_table - pubg = PublicationGroup.arel_table - only_numbers = sanitized_uids.select { |suid| suid.second.blank? }.map(&:first) only_versions = sanitized_uids.select { |suid| suid.first.blank? }.map(&:second) full_uids = sanitized_uids.reject { |suid| suid.first.blank? || suid.second.blank? } @@ -179,7 +181,6 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - acct = OpenStax::Accounts::Account.arel_table @items = @items.joins(publication: { authors: { user: :account } }).where( acct[:username].matches_any(sn) .or(acct[:first_name].matches_any(sn)) @@ -193,7 +194,6 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - acct = OpenStax::Accounts::Account.arel_table @items = @items.joins(publication: { copyright_holders: { user: :account } }).where( acct[:username].matches_any(sn) .or(acct[:first_name].matches_any(sn)) @@ -207,8 +207,6 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - acct_author = OpenStax::Accounts::Account.arel_table - acct_copyright = OpenStax::Accounts::Account.arel_table.alias('accounts_users') @items = @items.joins(publication: { authors: { user: :account } }) .joins(publication: { copyright_holders: { user: :account } }).where( acct_author[:username].matches_any(sn) @@ -223,16 +221,13 @@ def exec(params = {}, options = {}) end end - pg = PublicationGroup.arel_table - pb = Publication.arel_table - outputs.items = outputs.items.select( [ - Exercise.arel_table[ Arel.star ], - pg[:uuid], - pg[:number], - pb[:version], - pb[:published_at] + ex[ Arel.star ], + pubg[:uuid], + pubg[:number], + pub[:version], + pub[:published_at] ] ).distinct diff --git a/app/routines/search_vocab_terms.rb b/app/routines/search_vocab_terms.rb index 2998e97e..60907d6b 100644 --- a/app/routines/search_vocab_terms.rb +++ b/app/routines/search_vocab_terms.rb @@ -33,16 +33,24 @@ def exec(params = {}, options = {}) # this "latest_visible" condition is disabled. latest_visible = true + vt = VocabTerm.arel_table + pubg = PublicationGroup.arel_table + pub = Publication.arel_table + acct = OpenStax::Accounts::Account.arel_table + # NB: this encapsulates magic knowledge of how ActiveRecord will alias the second join of accounts + acct_author = OpenStax::Accounts::Account.arel_table + acct_copyright = OpenStax::Accounts::Account.arel_table.alias('accounts_users') + + run(:search, relation: relation, sortable_fields: SORTABLE_FIELDS, params: params) do |with| # Block to be used for searches by name or term name_search_block = lambda do |names| - vt = VocabTerm.arel_table names.each do |nm| sanitized_names = to_string_array(nm, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_names.empty? - @items = @items.where ( vt[:name].matches_any(sanitized_names )) + @items = @items.where( vt[:name].matches_any(sanitized_names )) end end @@ -74,10 +82,6 @@ def exec(params = {}, options = {}) elsif sanitized_versions.empty? @items = @items.where(publication_groups: { number: sanitized_numbers }) else - # Combine the id's one at a time using Squeel - pub = Publication.arel_table - pubg = PublicationGroup.arel_table - only_numbers = sanitized_uids.select { |suid| suid.second.blank? }.map(&:first) only_versions = sanitized_uids.select { |suid| suid.first.blank? }.map(&:second) full_uids = sanitized_uids.reject { |suid| suid.first.blank? || suid.second.blank? } @@ -163,7 +167,6 @@ def exec(params = {}, options = {}) with.keyword :term, &name_search_block with.keyword :definition do |definitions| - vt = VocabTerm.arel_table definitions.each do |df| sanitized_definitions = to_string_array(df, append_wildcard: true, prepend_wildcard: true) next @items = @items.none if sanitized_definitions.empty? @@ -173,7 +176,6 @@ def exec(params = {}, options = {}) end with.keyword :content do |contents| - vt = VocabTerm.arel_table contents.each do |content| sanitized_contents = to_string_array(content, append_wildcard: true, prepend_wildcard: true) @@ -189,7 +191,6 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - acct = OpenStax::Accounts::Account.arel_table @items = @items.joins(publication: { authors: { user: :account } }).where( acct[:username].matches_any(sn) .or(acct[:first_name].matches_any(sn)) @@ -203,7 +204,6 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - acct = OpenStax::Accounts::Account.arel_table @items = @items.joins(publication: { copyright_holders: { user: :account } }).where( acct[:username].matches_any(sn) .or(acct[:first_name].matches_any(sn)) @@ -217,8 +217,6 @@ def exec(params = {}, options = {}) sn = to_string_array(name, append_wildcard: true) next @items = @items.none if sn.empty? - acct_author = OpenStax::Accounts::Account.arel_table - acct_copyright = OpenStax::Accounts::Account.arel_table.alias('accounts_users') @items = @items.joins(publication: { authors: { user: :account } }) .joins(publication: { copyright_holders: { user: :account } }).where( acct_author[:username].matches_any(sn) @@ -233,16 +231,13 @@ def exec(params = {}, options = {}) end end - pg = PublicationGroup.arel_table - pb = Publication.arel_table - outputs.items = outputs.items.select( [ - VocabTerm.arel_table[ Arel.star ], - pg[:uuid], - pg[:number], - pb[:version], - pb[:published_at] + vt[ Arel.star ], + pubg[:uuid], + pubg[:number], + pub[:version], + pub[:published_at] ] ).distinct From d3f2915e683528661f1c7c7db582475face6981d Mon Sep 17 00:00:00 2001 From: Ross Reedstrom Date: Mon, 10 Jun 2019 11:53:47 -0500 Subject: [PATCH 50/50] switched to bundler-2 --- .travis.yml | 2 ++ Gemfile.lock | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7389ef7f..182e6f5d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,3 +21,5 @@ before_script: before_install: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" + - gem install bundler:2.0.1 + diff --git a/Gemfile.lock b/Gemfile.lock index 0a3a9daa..51e1e10e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -587,4 +587,4 @@ DEPENDENCIES whenever BUNDLED WITH - 1.17.3 + 2.0.1