From ffc14e499a12717fea96127d3cd5cd38f3ec41c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Tue, 22 Mar 2022 18:56:20 +0100 Subject: [PATCH 01/15] Upgrade to Rails 6.0 All the code in the `bin/` and the `config/` folders has been generated running `rake app:update`. The only exception is the code in `config/application.rb` where we've excluded the engines that Rails 6.0 has added, since we don't use them. There are a few changes in Active Storage which aren't compatible with the code we were using until now. Since the method to assign an attachment in ActiveStorage has changed and is incompatible with the hack we used to allow assigning `nil` attachments, and since ActiveStorage now supports assigning `nil` attachments, we're removing the mentioned hack. This makes the HasAttachment module redundant, so we're removing it. Another change in ActiveStorage is files are no longer saved before saving the `ActiveStorage::Attachment` record. This means we need to manually upload the file when using direct uploads. We also have to change the width and height validations we used for images; however, doing so results in very complex code, and we currently have to write that code for both images and site customization images. So, for now, we're just uploading the file before checking its dimensions. Not ideal, though. We might use active_storage_validations in the future to fix this issue (when they support a proc/lambda, as mentioned in commit 600f5c35e). We also need to update a couple of tests due to a small change in response headers. Now the content disposition returns something like: ``` attachment; filename="budget_investments.csv"; filename*=UTF-8''budget_investments.csv ``` So we're updating regular expression we use to check the filename. Finally, Rails 6.0.1 changed the way the host is set in integration tests [1] and so both `Capybara.app_host` and `Capybara.default_host` were ignored when generating URLs in the relationable examples. The only way I've found to make it work is to explicitely assign the host to the integration session. Rails 6.1 will change this setup again, so maybe then we can remove this hack. [1] https://github.com/rails/rails/pull/36283/commits/fe00711e9 --- Gemfile | 2 +- Gemfile.lock | 112 ++++++++++-------- app/models/concerns/attachable.rb | 3 +- app/models/concerns/has_attachment.rb | 17 --- app/models/direct_upload.rb | 1 + app/models/image.rb | 5 +- app/models/site_customization/image.rb | 10 +- bin/setup | 10 +- config/application.rb | 17 ++- config/environments/development.rb | 7 +- config/environments/production.rb | 32 ++++- config/environments/staging.rb | 31 ++++- config/environments/test.rb | 21 ++-- .../initializers/content_security_policy.rb | 3 + .../new_framework_defaults_6_0.rb | 45 +++++++ ..._attachments_for_blob_id.active_storage.rb | 10 ++ db/schema.rb | 10 +- spec/lib/tasks/files_spec.rb | 4 + spec/shared/system/relationable.rb | 6 +- spec/system/admin/budget_investments_spec.rb | 2 +- .../admin/emails/emails_download_spec.rb | 2 +- 21 files changed, 241 insertions(+), 109 deletions(-) delete mode 100644 app/models/concerns/has_attachment.rb create mode 100644 config/initializers/new_framework_defaults_6_0.rb create mode 100644 db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb diff --git a/Gemfile b/Gemfile index 6becfaf42..20ed8d928 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source "https://rubygems.org" -gem "rails", "5.2.8.1" +gem "rails", "6.0.5.1" gem "acts-as-taggable-on", "~> 8.1.0" gem "acts_as_votable", "~> 0.13.1" diff --git a/Gemfile.lock b/Gemfile.lock index bfc8bd2ac..14f5f5934 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,47 +2,61 @@ GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ specs: - actioncable (5.2.8.1) - actionpack (= 5.2.8.1) + actioncable (6.0.5.1) + actionpack (= 6.0.5.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) + actionmailbox (6.0.5.1) + actionpack (= 6.0.5.1) + activejob (= 6.0.5.1) + activerecord (= 6.0.5.1) + activestorage (= 6.0.5.1) + activesupport (= 6.0.5.1) + mail (>= 2.7.1) + actionmailer (6.0.5.1) + actionpack (= 6.0.5.1) + actionview (= 6.0.5.1) + activejob (= 6.0.5.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.8.1) - actionview (= 5.2.8.1) - activesupport (= 5.2.8.1) + actionpack (6.0.5.1) + actionview (= 6.0.5.1) + activesupport (= 6.0.5.1) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.8.1) - activesupport (= 5.2.8.1) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (6.0.5.1) + actionpack (= 6.0.5.1) + activerecord (= 6.0.5.1) + activestorage (= 6.0.5.1) + activesupport (= 6.0.5.1) + nokogiri (>= 1.8.5) + actionview (6.0.5.1) + activesupport (= 6.0.5.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.2.8.1) - activesupport (= 5.2.8.1) + rails-html-sanitizer (~> 1.1, >= 1.2.0) + activejob (6.0.5.1) + activesupport (= 6.0.5.1) globalid (>= 0.3.6) - activemodel (5.2.8.1) - activesupport (= 5.2.8.1) - activerecord (5.2.8.1) - activemodel (= 5.2.8.1) - activesupport (= 5.2.8.1) - arel (>= 9.0) - activestorage (5.2.8.1) - actionpack (= 5.2.8.1) - activerecord (= 5.2.8.1) - marcel (~> 1.0.0) - activesupport (5.2.8.1) + activemodel (6.0.5.1) + activesupport (= 6.0.5.1) + activerecord (6.0.5.1) + activemodel (= 6.0.5.1) + activesupport (= 6.0.5.1) + activestorage (6.0.5.1) + actionpack (= 6.0.5.1) + activejob (= 6.0.5.1) + activerecord (= 6.0.5.1) + marcel (~> 1.0) + activesupport (6.0.5.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) + zeitwerk (~> 2.2, >= 2.2.2) acts-as-taggable-on (8.1.0) activerecord (>= 5.0, < 6.2) acts_as_votable (0.13.1) @@ -64,7 +78,6 @@ GEM nokogiri ancestry (4.1.0) activerecord (>= 5.2.6) - arel (9.0.0) ast (2.4.2) audited (5.0.1) activerecord (>= 5.0, < 6.2) @@ -145,7 +158,7 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.9) + concurrent-ruby (1.1.10) coveralls (0.8.23) json (>= 1.8, < 3) simplecov (~> 0.16.1) @@ -276,7 +289,7 @@ GEM gitlab (4.17.0) httparty (~> 0.18) terminal-table (~> 1.5, >= 1.5.1) - globalid (0.5.2) + globalid (1.0.0) activesupport (>= 5.0) globalize (6.0.1) activemodel (>= 4.2, < 7.0) @@ -469,18 +482,20 @@ GEM rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.2.8.1) - actioncable (= 5.2.8.1) - actionmailer (= 5.2.8.1) - actionpack (= 5.2.8.1) - actionview (= 5.2.8.1) - activejob (= 5.2.8.1) - activemodel (= 5.2.8.1) - activerecord (= 5.2.8.1) - activestorage (= 5.2.8.1) - activesupport (= 5.2.8.1) + rails (6.0.5.1) + actioncable (= 6.0.5.1) + actionmailbox (= 6.0.5.1) + actionmailer (= 6.0.5.1) + actionpack (= 6.0.5.1) + actiontext (= 6.0.5.1) + actionview (= 6.0.5.1) + activejob (= 6.0.5.1) + activemodel (= 6.0.5.1) + activerecord (= 6.0.5.1) + activestorage (= 6.0.5.1) + activesupport (= 6.0.5.1) bundler (>= 1.3.0) - railties (= 5.2.8.1) + railties (= 6.0.5.1) sprockets-rails (>= 2.0.0) rails-assets-leaflet (1.5.1) rails-assets-markdown-it (9.0.1) @@ -489,15 +504,15 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.4.3) loofah (~> 2.3) - rails-i18n (5.1.3) + rails-i18n (6.0.0) i18n (>= 0.7, < 2) - railties (>= 5.0, < 6) - railties (5.2.8.1) - actionpack (= 5.2.8.1) - activesupport (= 5.2.8.1) + railties (>= 6.0.0, < 7) + railties (6.0.5.1) + actionpack (= 6.0.5.1) + activesupport (= 6.0.5.1) method_source rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) + thor (>= 0.20.3, < 2.0) rainbow (3.0.0) rake (13.0.6) rb-fsevent (0.10.4) @@ -627,7 +642,7 @@ GEM unicode-display_width (~> 1.1, >= 1.1.1) terrapin (0.6.0) climate_control (>= 0.0.3, < 1.0) - thor (1.1.0) + thor (1.2.1) thread_safe (0.3.6) tilt (2.0.10) tins (1.25.0) @@ -680,6 +695,7 @@ GEM wkhtmltopdf-binary (0.12.6.5) xpath (3.2.0) nokogiri (~> 1.8) + zeitwerk (2.6.0) PLATFORMS ruby @@ -753,7 +769,7 @@ DEPENDENCIES pronto-rubocop (~> 0.11.1) pronto-scss (~> 0.11.0) puma (~> 4.3.12) - rails (= 5.2.8.1) + rails (= 6.0.5.1) rails-assets-leaflet! rails-assets-markdown-it (~> 9.0.1)! recipient_interceptor (~> 0.3.0) diff --git a/app/models/concerns/attachable.rb b/app/models/concerns/attachable.rb index ac6c1e33a..cc457f934 100644 --- a/app/models/concerns/attachable.rb +++ b/app/models/concerns/attachable.rb @@ -1,9 +1,8 @@ module Attachable - include HasAttachment extend ActiveSupport::Concern included do - has_attachment :attachment + has_one_attached :attachment attr_accessor :cached_attachment validate :attachment_presence diff --git a/app/models/concerns/has_attachment.rb b/app/models/concerns/has_attachment.rb deleted file mode 100644 index 2ffbd931b..000000000 --- a/app/models/concerns/has_attachment.rb +++ /dev/null @@ -1,17 +0,0 @@ -module HasAttachment - extend ActiveSupport::Concern - - class_methods do - def has_attachment(attribute) - has_one_attached attribute - - define_method :"#{attribute}=" do |file| - if file.nil? - send(attribute).detach - else - send(attribute).attach(file) - end - end - end - end -end diff --git a/app/models/direct_upload.rb b/app/models/direct_upload.rb index cd562ca07..6d6eb7470 100644 --- a/app/models/direct_upload.rb +++ b/app/models/direct_upload.rb @@ -35,6 +35,7 @@ class DirectUpload def save_attachment @relation.attachment.blob.save! + @relation.attachment_changes["attachment"].upload end def persisted? diff --git a/app/models/image.rb b/app/models/image.rb index eda89ecc8..2f4cac7de 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -61,7 +61,10 @@ class Image < ApplicationRecord if accepted_content_types.include?(attachment_content_type) return true if imageable_class == Widget::Card - attachment.analyze unless attachment.analyzed? + unless attachment.analyzed? + attachment_changes["attachment"].upload + attachment.analyze + end width = attachment.metadata[:width] height = attachment.metadata[:height] diff --git a/app/models/site_customization/image.rb b/app/models/site_customization/image.rb index 7d69f74c1..ca68c0288 100644 --- a/app/models/site_customization/image.rb +++ b/app/models/site_customization/image.rb @@ -1,6 +1,4 @@ class SiteCustomization::Image < ApplicationRecord - include HasAttachment - VALID_IMAGES = { "logo_header" => [260, 80], "social_media_icon" => [470, 246], @@ -22,7 +20,7 @@ class SiteCustomization::Image < ApplicationRecord image/x-icon ].freeze - has_attachment :image + has_one_attached :image validates :name, presence: true, uniqueness: true, inclusion: { in: ->(*) { VALID_IMAGES.keys }} validates :image, file_content_type: { allow: ->(*) { VALID_MIME_TYPES }, if: -> { image.attached? }} @@ -61,7 +59,11 @@ class SiteCustomization::Image < ApplicationRecord def check_image return unless image.attached? - image.analyze unless image.analyzed? + unless image.analyzed? + attachment_changes["image"].upload + image.analyze + end + width = image.metadata[:width] height = image.metadata[:height] diff --git a/bin/setup b/bin/setup index aa921f10d..5635f8ec1 100755 --- a/bin/setup +++ b/bin/setup @@ -1,6 +1,5 @@ #!/usr/bin/env ruby require "fileutils" -include FileUtils # path to your application root. APP_ROOT = File.expand_path("..", __dir__) @@ -9,8 +8,9 @@ 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. +FileUtils.chdir APP_ROOT do + # This script is a way to setup or update your development environment automatically. + # This script is idempotent, so that you can run it at anytime and get an expectable outcome. # Add necessary setup steps to this file. puts "== Installing dependencies ==" @@ -19,11 +19,11 @@ chdir APP_ROOT do # puts "\n== Copying sample files ==" # unless File.exist?('config/database.yml') - # cp 'config/database.yml.sample', 'config/database.yml' + # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' # end puts "\n== Preparing database ==" - system! "bin/rails db:setup" + system! "bin/rails db:prepare" puts "\n== Removing old logs and tempfiles ==" system! "bin/rails log:clear tmp:clear" diff --git a/config/application.rb b/config/application.rb index a0de876cb..3d0b55b0f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,19 @@ require_relative "boot" -require "rails/all" +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "active_storage/engine" +require "action_controller/railtie" +require "action_mailer/railtie" +# require "action_mailbox/engine" +# require "action_text/engine" +require "action_view/railtie" +require "action_cable/engine" +require "sprockets/railtie" +require "rails/test_unit/railtie" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. @@ -27,7 +40,7 @@ module Consul # Handle custom exceptions config.action_dispatch.rescue_responses["FeatureFlags::FeatureDisabled"] = :forbidden - # Store files locally. + # Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. diff --git a/config/environments/development.rb b/config/environments/development.rb index 3b37e1e85..72d7ec69b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -16,6 +16,7 @@ Rails.application.configure do # Run rails dev:cache to toggle caching. if Rails.root.join("tmp", "caching-dev.txt").exist? config.action_controller.perform_caching = true + config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store config.public_file_server.headers = { @@ -50,14 +51,10 @@ Rails.application.configure do # number of complex assets. config.assets.debug = false - # Adds additional error checking when serving assets at runtime. - # Checks for improperly declared sprockets dependencies. - # Raises helpful error messages. - config.assets.raise_runtime_errors = true # Suppress logger output for asset requests. config.assets.quiet = true - # Raises error for missing translations + # Raises error for missing translations. # config.action_view.raise_on_missing_translations = true config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews" diff --git a/config/environments/production.rb b/config/environments/production.rb index cb680f167..9c8f2e683 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -19,6 +19,10 @@ Rails.application.configure do config.consider_all_requests_local = false config.action_controller.perform_caching = true + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? @@ -37,7 +41,7 @@ Rails.application.configure do # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX - # Mount Action Cable outside main process or domain + # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil # config.action_cable.url = "wss://example.com/cable" # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] @@ -56,9 +60,10 @@ Rails.application.configure do # Use a different cache store in production. config.cache_store = :mem_cache_store - # Use a real queuing backend for Active Job (and separate queues per environment) + # Use a real queuing backend for Active Job (and separate queues per environment). # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "consul_#{Rails.env}" + config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. @@ -90,9 +95,30 @@ Rails.application.configure do if ENV["RAILS_LOG_TO_STDOUT"].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) + config.logger = ActiveSupport::TaggedLogging.new(logger) end # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Inserts middleware to perform automatic connection switching. + # The `database_selector` hash is used to pass options to the DatabaseSelector + # middleware. The `delay` is used to determine how long to wait after a write + # to send a subsequent read to the primary. + # + # The `database_resolver` class is used by the middleware to determine which + # database is appropriate to use based on the time delay. + # + # The `database_resolver_context` class is used by the middleware to set + # timestamps for the last write to the primary. The resolver uses the context + # class timestamps to determine how long to wait before reading from the + # replica. + # + # By default Rails will store a last write timestamp in the session. The + # DatabaseSelector middleware is designed as such you can define your own + # strategy for connection switching and pass that into the middleware through + # these configuration options. + # config.active_record.database_selector = { delay: 2.seconds } + # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver + # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session end diff --git a/config/environments/staging.rb b/config/environments/staging.rb index d84df4300..f05d0a6ee 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -19,6 +19,10 @@ Rails.application.configure do config.consider_all_requests_local = false config.action_controller.perform_caching = true + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? @@ -37,7 +41,7 @@ Rails.application.configure do # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX - # Mount Action Cable outside main process or domain + # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil # config.action_cable.url = "wss://example.com/cable" # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] @@ -56,7 +60,7 @@ Rails.application.configure do # Use a different cache store in production. config.cache_store = :mem_cache_store - # Use a real queuing backend for Active Job (and separate queues per environment) + # Use a real queuing backend for Active Job (and separate queues per environment). # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "consul_#{Rails.env}" config.action_mailer.perform_caching = false @@ -90,9 +94,30 @@ Rails.application.configure do if ENV["RAILS_LOG_TO_STDOUT"].present? logger = ActiveSupport::Logger.new(STDOUT) logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) + config.logger = ActiveSupport::TaggedLogging.new(logger) end # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false + + # Inserts middleware to perform automatic connection switching. + # The `database_selector` hash is used to pass options to the DatabaseSelector + # middleware. The `delay` is used to determine how long to wait after a write + # to send a subsequent read to the primary. + # + # The `database_resolver` class is used by the middleware to determine which + # database is appropriate to use based on the time delay. + # + # The `database_resolver_context` class is used by the middleware to set + # timestamps for the last write to the primary. The resolver uses the context + # class timestamps to determine how long to wait before reading from the + # replica. + # + # By default Rails will store a last write timestamp in the session. The + # DatabaseSelector middleware is designed as such you can define your own + # strategy for connection switching and pass that into the middleware through + # these configuration options. + # config.active_record.database_selector = { delay: 2.seconds } + # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver + # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session end diff --git a/config/environments/test.rb b/config/environments/test.rb index 23ac6efa3..463b25f08 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,3 +1,8 @@ +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -6,10 +11,6 @@ Rails.application.configure do config.i18n.default_locale = :en config.i18n.available_locales = %w[de en es fr nl pt-BR zh-CN] - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Do not eager load code on boot. This avoids loading your whole application @@ -26,12 +27,17 @@ Rails.application.configure do # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false + config.cache_store = :null_store # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + config.action_mailer.perform_caching = false # Tell Action Mailer not to deliver emails to the real world. @@ -44,14 +50,9 @@ Rails.application.configure do # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - # Raises error for missing translations + # Raises error for missing translations. # config.action_view.raise_on_missing_translations = true - # Store files in tmp folders. - config.active_storage.service = :test - - config.cache_store = :null_store - config.after_initialize do Bullet.enable = true Bullet.bullet_logger = true diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index d3bcaa5ec..41c43016f 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -19,6 +19,9 @@ # If you are using UJS then enable automatic nonce generation # Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) } +# Set the nonce only to specific directives +# Rails.application.config.content_security_policy_nonce_directives = %w(script-src) + # 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 diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb new file mode 100644 index 000000000..92240ef5f --- /dev/null +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -0,0 +1,45 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 6.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. + +# Don't force requests from old versions of IE to be UTF-8 encoded. +# Rails.application.config.action_view.default_enforce_utf8 = false + +# Embed purpose and expiry metadata inside signed and encrypted +# cookies for increased security. +# +# This option is not backwards compatible with earlier Rails versions. +# It's best enabled when your entire app is migrated and stable on 6.0. +# Rails.application.config.action_dispatch.use_cookies_with_metadata = true + +# Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification. +# Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false + +# Return false instead of self when enqueuing is aborted from a callback. +# Rails.application.config.active_job.return_false_on_aborted_enqueue = true + +# Send Active Storage analysis and purge jobs to dedicated queues. +# Rails.application.config.active_storage.queues.analysis = :active_storage_analysis +# Rails.application.config.active_storage.queues.purge = :active_storage_purge + +# When assigning to a collection of attachments declared via `has_many_attached`, replace existing +# attachments instead of appending. Use #attach to add new attachments without replacing existing ones. +# Rails.application.config.active_storage.replace_on_assign_to_many = true + +# Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail. +# +# The default delivery jobs (ActionMailer::Parameterized::DeliveryJob, ActionMailer::DeliveryJob), +# will be removed in Rails 6.1. This setting is not backwards compatible with earlier Rails versions. +# If you send mail in the background, job workers need to have a copy of +# MailDeliveryJob to ensure all delivery jobs are processed properly. +# Make sure your entire app is migrated and stable on 6.0 before using this setting. +# Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob" + +# Enable the same cache key to be reused when the object being cached of type +# `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count) +# of the relation's cache key into the cache version to support recycling cache key. +# Rails.application.config.active_record.collection_cache_versioning = true diff --git a/db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb b/db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb new file mode 100644 index 000000000..ff5d72c7e --- /dev/null +++ b/db/migrate/20210924194527_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb @@ -0,0 +1,10 @@ +# This migration comes from active_storage (originally 20180723000244) +class AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId < ActiveRecord::Migration[6.0] + def up + return if foreign_key_exists?(:active_storage_attachments, column: :blob_id) + + if table_exists?(:active_storage_blobs) + add_foreign_key :active_storage_attachments, :active_storage_blobs, column: :blob_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 8d87806d6..b3cac4d02 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,11 +2,11 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `rails +# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. diff --git a/spec/lib/tasks/files_spec.rb b/spec/lib/tasks/files_spec.rb index 4d55334bb..5671aa208 100644 --- a/spec/lib/tasks/files_spec.rb +++ b/spec/lib/tasks/files_spec.rb @@ -12,7 +12,9 @@ describe "files tasks" do document = build(:document) image.attachment.blob.save! + image.attachment_changes["attachment"].upload document.attachment.blob.save! + document.attachment_changes["attachment"].upload travel_to(2.days.from_now) { run_rake_task } @@ -25,7 +27,9 @@ describe "files tasks" do document = build(:document) image.attachment.blob.save! + image.attachment_changes["attachment"].upload document.attachment.blob.save! + document.attachment_changes["attachment"].upload travel_to(2.minutes.from_now) { run_rake_task } diff --git a/spec/shared/system/relationable.rb b/spec/shared/system/relationable.rb index 5eb40de4f..50246fb29 100644 --- a/spec/shared/system/relationable.rb +++ b/spec/shared/system/relationable.rb @@ -3,7 +3,11 @@ shared_examples "relationable" do |relationable_model_name| let(:related1) { create([:proposal, :debate, :budget_investment].sample) } let(:related2) { create([:proposal, :debate, :budget_investment].sample) } let(:user) { create(:user) } - before { Setting["url"] = Capybara.app_host } + + before do + integration_session.host = Capybara.app_host # TODO: remove after upgrading to Rails 6.1 + Setting["url"] = Capybara.app_host + end scenario "related contents are listed" do create(:related_content, parent_relationable: relationable, child_relationable: related1, author: build(:user)) diff --git a/spec/system/admin/budget_investments_spec.rb b/spec/system/admin/budget_investments_spec.rb index 6430f62da..82af1feb0 100644 --- a/spec/system/admin/budget_investments_spec.rb +++ b/spec/system/admin/budget_investments_spec.rb @@ -1709,7 +1709,7 @@ describe "Admin budget investments", :admin do header = page.response_headers["Content-Disposition"] expect(header).to match(/^attachment/) - expect(header).to match(/filename="budget_investments.csv"$/) + expect(header).to match(/filename="budget_investments.csv"/) csv_contents = "ID,Title,Supports,Administrator,Valuator,Valuation Group,Scope of operation,"\ "Feasibility,Val. Fin.,Selected,Show to valuators,Author username\n"\ diff --git a/spec/system/admin/emails/emails_download_spec.rb b/spec/system/admin/emails/emails_download_spec.rb index 26facab75..cabfcf5c3 100644 --- a/spec/system/admin/emails/emails_download_spec.rb +++ b/spec/system/admin/emails/emails_download_spec.rb @@ -32,7 +32,7 @@ describe "Admin download user emails" do header = page.response_headers["Content-Disposition"] expect(header).to match(/^attachment/) - expect(header).to match(/filename="Administrators.csv"$/) + expect(header).to match(/filename="Administrators.csv"/) file_contents = page.body.split(",") expect(file_contents).to match_array ["admin_news1@consul.dev", "admin_news2@consul.dev"] From 7f7195ac0d34fbad1cfb15c98623085d1a57628d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 01:48:41 +0200 Subject: [PATCH 02/15] Remove hidden UTF input in forms This feature was kept in Rails mainly for Internet Explorer 8 and earlier. But those browsers are now used by less than 0.1% of the population, and we already display an alert for people using that browser, warning we don't support it. --- config/initializers/new_framework_defaults_6_0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb index 92240ef5f..a43c39dc0 100644 --- a/config/initializers/new_framework_defaults_6_0.rb +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -7,7 +7,7 @@ # Read the Guide for Upgrading Ruby on Rails for more info on each option. # Don't force requests from old versions of IE to be UTF-8 encoded. -# Rails.application.config.action_view.default_enforce_utf8 = false +Rails.application.config.action_view.default_enforce_utf8 = false # Embed purpose and expiry metadata inside signed and encrypted # cookies for increased security. From 55d4d3cd5cebe8d881acd772d63dc31869674cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 01:54:55 +0200 Subject: [PATCH 03/15] Enable cookies with metadata This is the default encryption for cookies in Rails 6.0 applications. The reason it isn't enabled automatically for existing applications is these cookies are not compatible with running the application with Rails 5. Since this isn't our case, and existing cookies are still read correctly, we can safely enable it. --- config/initializers/new_framework_defaults_6_0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb index a43c39dc0..d5667abbf 100644 --- a/config/initializers/new_framework_defaults_6_0.rb +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -14,7 +14,7 @@ Rails.application.config.action_view.default_enforce_utf8 = false # # This option is not backwards compatible with earlier Rails versions. # It's best enabled when your entire app is migrated and stable on 6.0. -# Rails.application.config.action_dispatch.use_cookies_with_metadata = true +Rails.application.config.action_dispatch.use_cookies_with_metadata = true # Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification. # Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false From 8d7ce6f428994093c5433c75f302df1e5bd27890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 02:08:16 +0200 Subject: [PATCH 04/15] Return content-type header without modification This is the default in Rails 6.0. I don't think it affects us, though. --- config/initializers/new_framework_defaults_6_0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb index d5667abbf..38c836561 100644 --- a/config/initializers/new_framework_defaults_6_0.rb +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -17,7 +17,7 @@ Rails.application.config.action_view.default_enforce_utf8 = false Rails.application.config.action_dispatch.use_cookies_with_metadata = true # Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification. -# Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false +Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false # Return false instead of self when enqueuing is aborted from a callback. # Rails.application.config.active_job.return_false_on_aborted_enqueue = true From 3302f8c64d1773a3c18f351d155706d9283fb850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 02:40:04 +0200 Subject: [PATCH 05/15] Return false on aborted enqueue in Active Job In order to prevent a warning: ``` Rails 6.1 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true` to remove the deprecations. ``` --- config/initializers/new_framework_defaults_6_0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb index 38c836561..91e3f6efb 100644 --- a/config/initializers/new_framework_defaults_6_0.rb +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -20,7 +20,7 @@ Rails.application.config.action_dispatch.use_cookies_with_metadata = true Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false # Return false instead of self when enqueuing is aborted from a callback. -# Rails.application.config.active_job.return_false_on_aborted_enqueue = true +Rails.application.config.active_job.return_false_on_aborted_enqueue = true # Send Active Storage analysis and purge jobs to dedicated queues. # Rails.application.config.active_storage.queues.analysis = :active_storage_analysis From 390a82ff8edbe743f8f231324a86f7c9439f03e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 02:55:27 +0200 Subject: [PATCH 06/15] Use Rails 6 attachments defaults in Active Storage In Active Storage 5.2 there was an unexpected behavior: assigning a collection appended records to the existing collection, instead of replacing them as it's done in Active Record associations. It doesn't really affect us, though, since we don't use `has_many_attached` anywhere. --- config/initializers/new_framework_defaults_6_0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb index 91e3f6efb..f8cfdd436 100644 --- a/config/initializers/new_framework_defaults_6_0.rb +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -28,7 +28,7 @@ Rails.application.config.active_job.return_false_on_aborted_enqueue = true # When assigning to a collection of attachments declared via `has_many_attached`, replace existing # attachments instead of appending. Use #attach to add new attachments without replacing existing ones. -# Rails.application.config.active_storage.replace_on_assign_to_many = true +Rails.application.config.active_storage.replace_on_assign_to_many = true # Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail. # From af1244654cd68672a00b7eb14320fd0594905bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 03:12:59 +0200 Subject: [PATCH 07/15] Use MailDeliveryJob to send mail in the background The default delivery job class in Rails 5.2 (ActionMailer::DeliveryJob) is deprecated. This option wasn't already enabled in order to ease the upgrade, since after upgrading with Rails 6 `MailDeliveryJob`, it won't be possible to downgrade to Rails 5.2 without risking some crashes in background jobs. --- config/initializers/new_framework_defaults_6_0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb index f8cfdd436..2d66e49a2 100644 --- a/config/initializers/new_framework_defaults_6_0.rb +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -37,7 +37,7 @@ Rails.application.config.active_storage.replace_on_assign_to_many = true # If you send mail in the background, job workers need to have a copy of # MailDeliveryJob to ensure all delivery jobs are processed properly. # Make sure your entire app is migrated and stable on 6.0 before using this setting. -# Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob" +Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob" # Enable the same cache key to be reused when the object being cached of type # `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count) From 1ea4988e525322145155aa9f346b371a993007be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 03:38:54 +0200 Subject: [PATCH 08/15] Enable collection cache versioning Similar to the way we enabled cache versioning in commit e01a94d7b. This only affects caching `ActiveRecord::Relation` objects. I'm not even sure we cache these objects, though, so we're just enabling the option because it's the default one in Rails 6.0. --- config/initializers/new_framework_defaults_6_0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb index 2d66e49a2..d254fa8e7 100644 --- a/config/initializers/new_framework_defaults_6_0.rb +++ b/config/initializers/new_framework_defaults_6_0.rb @@ -42,4 +42,4 @@ Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliver # Enable the same cache key to be reused when the object being cached of type # `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count) # of the relation's cache key into the cache version to support recycling cache key. -# Rails.application.config.active_record.collection_cache_versioning = true +Rails.application.config.active_record.collection_cache_versioning = true From 7fe2309762b93a06f04e87fd4867b340a49bce89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 03:55:30 +0200 Subject: [PATCH 09/15] Use Rails 6.0 defaults and overwrite them We can remove the `new_framework_defaults_6_0` file by using Rails 6.0 default options and overwriting the ones we haven't enabled. We're still using the classic autoloader because we still haven't checked how switching to zeitwerk will affect the way CONSUL installations customize their code. And we're using the default queues for Active Storage because we were already using them and that will be the default option in Rails 6.1. --- config/application.rb | 11 ++++- .../new_framework_defaults_6_0.rb | 45 ------------------- 2 files changed, 10 insertions(+), 46 deletions(-) delete mode 100644 config/initializers/new_framework_defaults_6_0.rb diff --git a/config/application.rb b/config/application.rb index 3d0b55b0f..4702a0715 100644 --- a/config/application.rb +++ b/config/application.rb @@ -21,7 +21,7 @@ Bundler.require(*Rails.groups) module Consul class Application < Rails::Application - config.load_defaults 5.2 + config.load_defaults 6.0 # Keep belongs_to fields optional by default, because that's the way # Rails 4 models worked @@ -34,6 +34,15 @@ module Consul # in any CONSUL installations config.active_support.use_authenticated_message_encryption = false + # Keep using the classic autoloader until we decide how custom classes + # should work with zeitwerk + config.autoloader = :classic + + # Use the default queue for ActiveStorage like we were doing with Rails 5.2 + # because it will also be the default in Rails 6.1. + config.active_storage.queues.analysis = nil + config.active_storage.queues.purge = nil + # Keep reading existing data in the legislation_annotations ranges column config.active_record.yaml_column_permitted_classes = [ActiveSupport::HashWithIndifferentAccess, Symbol] diff --git a/config/initializers/new_framework_defaults_6_0.rb b/config/initializers/new_framework_defaults_6_0.rb deleted file mode 100644 index d254fa8e7..000000000 --- a/config/initializers/new_framework_defaults_6_0.rb +++ /dev/null @@ -1,45 +0,0 @@ -# Be sure to restart your server when you modify this file. -# -# This file contains migration options to ease your Rails 6.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. - -# Don't force requests from old versions of IE to be UTF-8 encoded. -Rails.application.config.action_view.default_enforce_utf8 = false - -# Embed purpose and expiry metadata inside signed and encrypted -# cookies for increased security. -# -# This option is not backwards compatible with earlier Rails versions. -# It's best enabled when your entire app is migrated and stable on 6.0. -Rails.application.config.action_dispatch.use_cookies_with_metadata = true - -# Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification. -Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false - -# Return false instead of self when enqueuing is aborted from a callback. -Rails.application.config.active_job.return_false_on_aborted_enqueue = true - -# Send Active Storage analysis and purge jobs to dedicated queues. -# Rails.application.config.active_storage.queues.analysis = :active_storage_analysis -# Rails.application.config.active_storage.queues.purge = :active_storage_purge - -# When assigning to a collection of attachments declared via `has_many_attached`, replace existing -# attachments instead of appending. Use #attach to add new attachments without replacing existing ones. -Rails.application.config.active_storage.replace_on_assign_to_many = true - -# Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail. -# -# The default delivery jobs (ActionMailer::Parameterized::DeliveryJob, ActionMailer::DeliveryJob), -# will be removed in Rails 6.1. This setting is not backwards compatible with earlier Rails versions. -# If you send mail in the background, job workers need to have a copy of -# MailDeliveryJob to ensure all delivery jobs are processed properly. -# Make sure your entire app is migrated and stable on 6.0 before using this setting. -Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob" - -# Enable the same cache key to be reused when the object being cached of type -# `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count) -# of the relation's cache key into the cache version to support recycling cache key. -Rails.application.config.active_record.collection_cache_versioning = true From 7c8e3788ec1cea62bfaa0540b16f4bb6d837146b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 14:01:53 +0200 Subject: [PATCH 10/15] Use new module_parent and module_parents methods We were getting some deprecation warnings: DEPRECATION WARNING: `Module#parent` has been renamed to `module_parent`. `parent` is deprecated and will be removed in Rails 6.1. DEPRECATION WARNING: `Module#parents` has been renamed to `module_parents`. `parents` is deprecated and will be removed in Rails 6.1. --- app/components/admin/menu_component.html.erb | 4 ++-- app/components/admin/menu_component.rb | 14 +++++++------- app/helpers/translatable_form_helper.rb | 2 +- app/views/layouts/admin.html.erb | 2 +- app/views/shared/_subnavigation.html.erb | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/components/admin/menu_component.html.erb b/app/components/admin/menu_component.html.erb index 40e501dc5..750ee18ec 100644 --- a/app/components/admin/menu_component.html.erb +++ b/app/components/admin/menu_component.html.erb @@ -22,7 +22,7 @@ <% end %> <% if feature?(:legislation) %> -
  • "> +
  • "> <%= link_to t("admin.menu.legislation"), admin_legislation_processes_path, class: "legislation-link" %>
  • <% end %> @@ -69,7 +69,7 @@ banners_link, information_texts_link, documents_link, - class: ("is-active" if customization? && controller.class.parent != Admin::Poll::Questions::Answers) + class: ("is-active" if customization? && controller.class.module_parent != Admin::Poll::Questions::Answers) ) %> diff --git a/app/components/admin/menu_component.rb b/app/components/admin/menu_component.rb index 15e15f2b1..4ef5d262f 100644 --- a/app/components/admin/menu_component.rb +++ b/app/components/admin/menu_component.rb @@ -4,7 +4,7 @@ class Admin::MenuComponent < ApplicationComponent private def moderated_content? - moderated_sections.include?(controller_name) && controller.class.parent != Admin::Legislation + moderated_sections.include?(controller_name) && controller.class.module_parent != Admin::Legislation end def moderated_sections @@ -17,7 +17,7 @@ class Admin::MenuComponent < ApplicationComponent end def polls? - controller.class.parent == Admin::Poll::Questions::Answers || + controller.class.module_parent == Admin::Poll::Questions::Answers || %w[polls active_polls recounts results questions answers].include?(controller_name) && action_name != "booth_assignments" end @@ -35,7 +35,7 @@ class Admin::MenuComponent < ApplicationComponent controllers_names = ["settings", "tags", "geozones", "images", "content_blocks", "local_census_records", "imports"] controllers_names.include?(controller_name) && - controller.class.parent != Admin::Poll::Questions::Answers + controller.class.module_parent != Admin::Poll::Questions::Answers end def customization? @@ -57,7 +57,7 @@ class Admin::MenuComponent < ApplicationComponent def local_census_records? controller_name == "local_census_records" || - (controller_name == "imports" && controller.class.parent == Admin::LocalCensusRecords) + (controller_name == "imports" && controller.class.module_parent == Admin::LocalCensusRecords) end def messages_menu_active? @@ -69,11 +69,11 @@ class Admin::MenuComponent < ApplicationComponent end def sdg_managers? - controller_name == "managers" && controller.class.parent == Admin::SDG + controller_name == "managers" && controller.class.module_parent == Admin::SDG end def managers? - controller_name == "managers" && controller.class.parent == Admin + controller_name == "managers" && controller.class.module_parent == Admin end def officers_link @@ -320,7 +320,7 @@ class Admin::MenuComponent < ApplicationComponent [ t("admin.menu.site_customization.images"), admin_site_customization_images_path, - controller_name == "images" && controller.class.parent != Admin::Poll::Questions::Answers + controller_name == "images" && controller.class.module_parent != Admin::Poll::Questions::Answers ] end diff --git a/app/helpers/translatable_form_helper.rb b/app/helpers/translatable_form_helper.rb index fea9b04ef..8b15255c3 100644 --- a/app/helpers/translatable_form_helper.rb +++ b/app/helpers/translatable_form_helper.rb @@ -8,7 +8,7 @@ module TranslatableFormHelper end def backend_translations_enabled? - (controller.class.parents & [Admin, Management, Valuation, SDGManagement]).any? + (controller.class.module_parents & [Admin, Management, Valuation, SDGManagement]).any? end def highlight_translation_html_class diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index 1a78ad60a..47cba9f90 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb @@ -27,7 +27,7 @@ "aria-hidden": true, class: "button hollow expanded" %> <%= render "layouts/flash" %> - <%= render "layouts/officing_booth" if controller.class.parent == Officing && session[:booth_id].present? %> + <%= render "layouts/officing_booth" if controller.class.module_parent == Officing && session[:booth_id].present? %> <%= yield %> diff --git a/app/views/shared/_subnavigation.html.erb b/app/views/shared/_subnavigation.html.erb index 1c81f389a..4df7ff1d8 100644 --- a/app/views/shared/_subnavigation.html.erb +++ b/app/views/shared/_subnavigation.html.erb @@ -22,7 +22,7 @@
  • <%= layout_menu_link_to t("layouts.header.poll_questions"), polls_path, - controller_name == "polls" || (controller_name == "questions" && controller.class.parent == Polls), + controller_name == "polls" || (controller_name == "questions" && controller.class.module_parent == Polls), accesskey: "3" %>
  • <% end %> @@ -30,7 +30,7 @@
  • <%= layout_menu_link_to t("layouts.header.collaborative_legislation"), legislation_processes_path, - controller.class.parent == Legislation, + controller.class.module_parent == Legislation, accesskey: "4" %>
  • <% end %> From 19da667478f22f794f0c71aef7f462abbbae7506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 14:10:42 +0200 Subject: [PATCH 11/15] Include default locale in fallbacks explicitly We were getting a warning because it won't be included by default in Rails 6.1: DEPRECATION WARNING: Using I18n fallbacks with an empty `defaults` sets the defaults to include the `default_locale`. This behavior will change in Rails 6.1 . If you desire the default locale to be included in the defaults, please explicitly configure it with `config.i18n.fallbacks.defaults = [I18n.default_locale]` or `config.i18n.fallbacks = [I18n.default_locale, {...}]`. If you want to opt-in to the new behavior, use `config.i18n.fallbacks.defaults = [nil, {...}] `. --- config/application.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/application.rb b/config/application.rb index 4702a0715..d18d64a15 100644 --- a/config/application.rb +++ b/config/application.rb @@ -97,7 +97,7 @@ module Consul "zh-CN", "zh-TW"] config.i18n.available_locales = available_locales - config.i18n.fallbacks = { + config.i18n.fallbacks = [I18n.default_locale, { "ca" => "es", "es-PE" => "es", "eu" => "es", @@ -107,7 +107,7 @@ module Consul "oc" => "fr", "pt-BR" => "es", "val" => "es" - } + }] config.i18n.load_path += Dir[Rails.root.join("config", "locales", "**[^custom]*", "*.{rb,yml}")] config.i18n.load_path += Dir[Rails.root.join("config", "locales", "custom", "**", "*.{rb,yml}")] From a72572eb64570be706f63bb9230d6411d88048d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 18 Sep 2021 19:16:47 +0200 Subject: [PATCH 12/15] Add image_processing gem dependency It's now used by default to handle image variants. We were getting a warning: DEPRECATION WARNING: Generating image variants will require the image_processing gem in Rails 6.1. Please add `gem 'image_processing', '~> 1.2'` to your Gemfile. Note `mini_magick` is required in order to use the `analyze` method [1]. Since we use it in our image (and site customization image) validations, we're still keeping the explicit dependency in our Gemfile. [1] https://guides.rubyonrails.org/v6.0/active_storage_overview.html#analyzing-files --- Gemfile | 1 + Gemfile.lock | 6 ++++++ app/models/image.rb | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 20ed8d928..5302f6eb2 100644 --- a/Gemfile +++ b/Gemfile @@ -28,6 +28,7 @@ gem "globalize-accessors", "~> 0.3.0" gem "graphiql-rails", "~> 1.7.0" gem "graphql", "~> 1.12.14" gem "groupdate", "~> 5.2.2" +gem "image_processing", "~> 1.12.2" gem "initialjs-rails", "~> 0.2.0.9" gem "invisible_captcha", "~> 2.0.0" gem "jquery-fileupload-rails" diff --git a/Gemfile.lock b/Gemfile.lock index 14f5f5934..8e93b1c3d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -328,6 +328,9 @@ GEM rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) ice_nine (0.11.2) + image_processing (1.12.2) + mini_magick (>= 4.9.5, < 5) + ruby-vips (>= 2.0.17, < 3) initialjs-rails (0.2.0.9) railties (>= 3.1, < 7.0) invisible_captcha (2.0.0) @@ -570,6 +573,8 @@ GEM rubocop (~> 1.0) rubocop-ast (>= 1.1.0) ruby-progressbar (1.11.0) + ruby-vips (2.1.4) + ffi (~> 1.12) ruby2_keywords (0.0.5) rubyzip (2.3.2) rugged (1.0.1) @@ -744,6 +749,7 @@ DEPENDENCIES graphql (~> 1.12.14) groupdate (~> 5.2.2) i18n-tasks (~> 0.9.34) + image_processing (~> 1.12.2) initialjs-rails (~> 0.2.0.9) invisible_captcha (~> 2.0.0) jquery-fileupload-rails diff --git a/app/models/image.rb b/app/models/image.rb index 2f4cac7de..4d479d282 100644 --- a/app/models/image.rb +++ b/app/models/image.rb @@ -4,8 +4,8 @@ class Image < ApplicationRecord def self.styles { large: { resize: "x#{Setting["uploads.images.min_height"]}" }, - medium: { combine_options: { gravity: "center", resize: "300x300^", crop: "300x300+0+0" }}, - thumb: { combine_options: { gravity: "center", resize: "140x245^", crop: "140x245+0+0" }} + medium: { gravity: "center", resize: "300x300^", crop: "300x300+0+0" }, + thumb: { gravity: "center", resize: "140x245^", crop: "140x245+0+0" } } end From 4732a6b22dfc22aab99718491ac0c5ca53c34f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sun, 19 Sep 2021 13:50:34 +0200 Subject: [PATCH 13/15] Bump web-console from 3.7.0 to 4.0.4 We were getting a warning after upgrading to Rails 6: DEPRECATION WARNING: ActionView::Base instances should be constructed with a lookup context, assignments, and a controller. We didn't upgrade web-console earlier because version 4.x isn't compatible with Rails 5. --- Gemfile | 2 +- Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 5302f6eb2..e3537bce2 100644 --- a/Gemfile +++ b/Gemfile @@ -113,7 +113,7 @@ group :development do gem "rubocop-rspec", "~> 2.4.0", require: false gem "rvm1-capistrano3", "~> 1.4.0", require: false gem "scss_lint", "~> 0.59.0", require: false - gem "web-console", "~> 3.7.0" + gem "web-console", "~> 4.0.4" end eval_gemfile "./Gemfile_custom" diff --git a/Gemfile.lock b/Gemfile.lock index 8e93b1c3d..ee0c8f765 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -680,11 +680,11 @@ GEM addressable httpi (~> 2.0) nokogiri (>= 1.4.2) - web-console (3.7.0) - actionview (>= 5.0) - activemodel (>= 5.0) + web-console (4.0.4) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) bindex (>= 0.4.0) - railties (>= 5.0) + railties (>= 6.0.0) webdrivers (4.6.0) nokogiri (~> 1.6) rubyzip (>= 1.3.0) @@ -803,7 +803,7 @@ DEPENDENCIES uglifier (~> 4.2.0) uuidtools (~> 2.1.5) view_component (~> 2.49.1) - web-console (~> 3.7.0) + web-console (~> 4.0.4) webdrivers (~> 4.6.0) whenever (~> 1.0.0) wicked_pdf (~> 2.1.0) From 0b613158da769f4694e93a31c556743268b52188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sun, 19 Sep 2021 14:00:37 +0200 Subject: [PATCH 14/15] Update TranslationHelper monkey-patch The `translate` method now receives keyword arguments instead of a hash of options. --- config/initializers/i18n_translation.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/initializers/i18n_translation.rb b/config/initializers/i18n_translation.rb index ae43e5fc0..69c933f35 100644 --- a/config/initializers/i18n_translation.rb +++ b/config/initializers/i18n_translation.rb @@ -6,7 +6,7 @@ module ActionView module TranslationHelper include TagHelper - def t(key, options = {}) + def t(key, **options) current_locale = options[:locale].presence || I18n.locale @i18n_content_translations ||= {} @@ -17,7 +17,7 @@ module ActionView if translation.present? translation % options else - translate(key, options) + translate(key, **options) end end end From 790170a27c842cfba6b211cccf4bebd55d0a6edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sun, 19 Sep 2021 16:14:34 +0200 Subject: [PATCH 15/15] Use keyword arguments in tag methods The interface of this method has changed and uses keyword arguments instead of a hash of options. This change will be particularly significant when upgrading to Ruby 3. --- .../admin/poll/officers/officers_component.html.erb | 2 +- app/components/admin/stats/stat_component.html.erb | 2 +- app/components/shared/link_list_component.html.erb | 2 +- app/components/shared/link_list_component.rb | 2 +- app/helpers/stats_helper.rb | 4 ++-- app/helpers/translatable_form_helper.rb | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/components/admin/poll/officers/officers_component.html.erb b/app/components/admin/poll/officers/officers_component.html.erb index f35ae2793..54784ebaf 100644 --- a/app/components/admin/poll/officers/officers_component.html.erb +++ b/app/components/admin/poll/officers/officers_component.html.erb @@ -1,4 +1,4 @@ -<%= tag.table options do %> +<%= tag.table(**options) do %> <%= t("admin.poll_officers.officer.name") %> diff --git a/app/components/admin/stats/stat_component.html.erb b/app/components/admin/stats/stat_component.html.erb index 684b016a3..fa5b95999 100644 --- a/app/components/admin/stats/stat_component.html.erb +++ b/app/components/admin/stats/stat_component.html.erb @@ -1,5 +1,5 @@
    - <%= tag.p(options) do %> + <%= tag.p(**options) do %> <%= text %>
    <%= amount %> <% end %>
    diff --git a/app/components/shared/link_list_component.html.erb b/app/components/shared/link_list_component.html.erb index 86239013b..dc001156e 100644 --- a/app/components/shared/link_list_component.html.erb +++ b/app/components/shared/link_list_component.html.erb @@ -1 +1 @@ -<%= tag.ul(options) { safe_join(list_items, "\n") } %> +<%= tag.ul(**options) { safe_join(list_items, "\n") } %> diff --git a/app/components/shared/link_list_component.rb b/app/components/shared/link_list_component.rb index 683bc80db..3a9a21b68 100644 --- a/app/components/shared/link_list_component.rb +++ b/app/components/shared/link_list_component.rb @@ -18,7 +18,7 @@ class Shared::LinkListComponent < ApplicationComponent def list_items present_links.map do |text, url, current = false, **link_options| - tag.li(({ "aria-current": true } if current)) do + tag.li("aria-current": (true if current)) do if url link_to text, url, link_options else diff --git a/app/helpers/stats_helper.rb b/app/helpers/stats_helper.rb index 867cab161..acc79319b 100644 --- a/app/helpers/stats_helper.rb +++ b/app/helpers/stats_helper.rb @@ -2,7 +2,7 @@ module StatsHelper def chart_tag(opt = {}) opt[:data] ||= {} opt[:data][:graph] = admin_api_stats_path(chart_data(opt)) - tag.div opt + tag.div(**opt) end def chart_data(opt = {}) @@ -26,7 +26,7 @@ module StatsHelper def budget_investments_chart_tag(opt = {}) opt[:data] ||= {} opt[:data][:graph] = admin_api_stats_path(budget_investments: true) - tag.div opt + tag.div(**opt) end def number_to_stats_percentage(number, options = {}) diff --git a/app/helpers/translatable_form_helper.rb b/app/helpers/translatable_form_helper.rb index 8b15255c3..6e73433c9 100644 --- a/app/helpers/translatable_form_helper.rb +++ b/app/helpers/translatable_form_helper.rb @@ -32,7 +32,7 @@ module TranslatableFormHelper def fields_for_locale(locale) fields_for_translation(@translations[locale]) do |translations_form| - @template.tag.div translations_options(translations_form.object, locale) do + @template.tag.div **translations_options(translations_form.object, locale) do @template.concat translations_form.hidden_field( :_destroy, value: !@template.enabled_locale?(translations_form.object.globalized_model, locale),