diff --git a/Dockerfile b/Dockerfile index 38ae401446..de50b7de84 100644 --- a/Dockerfile +++ b/Dockerfile @@ -59,7 +59,7 @@ FROM base AS assets-precompiler # http://blog.zeit.io/use-a-fake-db-adapter-to-play-nice-with-rails-assets-precompilation/ RUN bundle add activerecord-nulldb-adapter RUN printf "production:\n adapter: nulldb" > config/database.yml \ -&& printf "production:\n secret_key_base: $(bundle exec rake secret)" > config/secrets.yml +&& printf "production:\n secret_key_base: $(bundle exec rails secret)" > config/secrets.yml # Precompiling and also removing config files just in case someone uses `docker build --target=assets-precompiler` diff --git a/Gemfile b/Gemfile index e126ccdbec..0561580214 100644 --- a/Gemfile +++ b/Gemfile @@ -4,12 +4,12 @@ gem 'rack-cors', '~> 2.0', require: 'rack/cors' ruby '>= 3.2', '< 3.4.0' -gem 'bundler', '~> 2.0' +gem 'bundler', '~> 2.5' gem 'rake', '~> 13.0' -gem 'rails', '~> 6.1' +gem 'rails', '~> 7.1' gem 'pg', '~> 1.1' -gem 'activerecord-postgis-adapter', '~> 7.0' +gem 'activerecord-postgis-adapter', '~> 9.0' gem 'hiredis', '~> 0.6.1' gem 'redis', '~> 4.5' @@ -22,12 +22,15 @@ gem 'rubyzip', '~> 2.3.0' gem 'zip_tricks', '~> 5.6' gem 'daemons', '~> 1.4.1' gem 'tzinfo-data', '~> 1.2019' # , '>= 1.2019.3' -gem 'psych', '~> 3.3' +gem 'psych', '~> 5.1' gem 'rmagick', '~> 5.1' # , '>= 4.2.2' gem 'roo', '~> 2.8', '>= 2.8.3' gem 'roo-xls', '~> 1.2' -gem 'net-smtp', '~> 0.3.1' +gem 'csv', '~> 3.2' + + +gem 'net-smtp', '~> 0.4' gem 'mail', '~> 2.8', '>= 2.8.1' gem 'matrix', '~> 0.4.2' @@ -66,21 +69,30 @@ gem 'delayed_job_active_record', '~> 4.1.3' # TODO: updating to 5.0 causes "NoMethodError: undefined method `has_attached_file' for Image:Class" # This is likely not the real propegated error, see similar https://github.com/Shopify/bootsnap/issues/218 # version 6 beta out now -gem 'validates_timeliness', '~> 4.1', '>= 4.1.1' -gem 'paper_trail', '~> 12.0' + +gem 'validates_timeliness', '~> 7.0.0.beta2' # , '>= 4.1.1' + + + +gem 'paper_trail', '~> 15.0' + gem 'acts_as_list', '~> 1.0' gem 'modularity', '~> 3.0.0' # TODO: Used!? -gem 'paperclip', github: 'LocoDelAssembly/paperclip', branch: 'migration-fix' # gem 'paperclip', '~> 6.1.0' -gem 'paperclip-meta', '~> 3.0' # TODO: kt-paperclip can be installed but because of this gem old paperclip is installed as well and deprecation warnings continue + +gem 'kt-paperclip', '~> 7.2' + +# gem 'paperclip', github: 'LocoDelAssembly/paperclip', branch: 'migration-fix' # gem 'paperclip', '~> 6.1.0' +gem 'paperclip-meta', github: 'LocoDelAssembly/paperclip-meta', branch: 'kt-paperclip' + gem 'voight_kampff', github: 'LocoDelAssembly/Voight-Kampff' -gem 'shortener', '~> 1.0.0' +gem 'shortener', '~> 1.0' gem 'rails_or', '~> 1.1.8' # javascript -gem 'sprockets-rails', '~> 3.2.0' # UPDATE TODO -gem 'sprockets', '~> 3.7.2' # TODO: Cannot use '~> 4.0' (app fails to initialize properly) +gem 'sprockets-rails', '~> 3.4.0' # UPDATE TODO +gem 'sprockets', '~> 4.2' # TODO: Cannot use '~> 4.0' (app fails to initialize properly) gem 'sprockets-es6', '~> 0.9.2', require: 'sprockets/es6' -gem 'uglifier', '~> 4.2' +gem 'terser', '~> 1.2' gem 'jquery-rails', '~> 4.4' # gem 'jquery-ui-rails', '~> 6.0.1' @@ -92,17 +104,17 @@ gem 'jquery-turbolinks', '~> 2.1' gem 'shakapacker', '7.2.3' # BibTeX handling -gem 'csl', '~> 1.6.0' +gem 'csl', '~> 2.0' gem 'bibtex-ruby', '~> 6.0' -gem 'citeproc-ruby', '~> 1.1.10' -gem 'csl-styles', '~> 1.0.1.8' +gem 'citeproc-ruby', '~> 2.0' +gem 'csl-styles', '~> 2.0.1' gem 'serrano', github: 'LocoDelAssembly/serrano', branch: 'older_thor' #gem 'serrano', '~> 1.0.0' # gem 'latex-decode', '~> 0.2.2' gem 'pdf-reader', '~> 2.2' # UI/UX -gem 'chartkick', '~> 4.0' -gem 'groupdate', '~> 5.2' +gem 'chartkick', '~> 5.0' +gem 'groupdate', '~> 6.4' gem 'dropzonejs-rails', '~> 0.8.1' gem 'kaminari', '~> 1.2.0' gem 'best_in_place', git: 'https://github.com/mmotherwell/best_in_place' @@ -130,16 +142,16 @@ gem 'colrapi', '~>0.1.1' gem 'gnfinder', '~> 1.0' # Minor Utils/helpers -gem 'amazing_print', '~> 1.4.0' +gem 'amazing_print', '~> 1.5' gem 'indefinite_article', '~> 0.2.4' -gem 'rainbow', '~> 3.0.0' +gem 'rainbow', '~> 3.0' gem 'term-ansicolor', '~> 1.6' # DEPRECATED gem 'chronic', '~> 0.10.2' gem 'logical_query_parser' gem 'logic_tools' gem 'chunky_png', '~> 1.4.0' gem 'namecase', '~> 2.0' -gem 'zaru', '~> 0.3.0' +gem 'zaru', '~> 1.0' # Export gem 'asciidoctor', '~> 2.0' @@ -153,8 +165,8 @@ gem 'parallel', '~> 1.23' gem 'ruby-progressbar', '~> 1.11' group :test, :development do - gem 'faker', '~> 2.10' - gem 'rspec-rails', '~> 5.0' + gem 'faker', '~> 3.2' + gem 'rspec-rails', '~> 6.1' gem 'rspec-activemodel-mocks', '~> 1.1.0' gem 'byebug', '~> 11.1', {}.merge(ENV['RM_INFO'] ? {require: false} : {}) gem 'factory_bot_rails', '~> 6.2' @@ -181,12 +193,12 @@ group :development do gem 'rubocop-rspec', '~>2.6' gem 'rubocop-faker', '~> 1.1' gem 'rubocop-performance', '~> 1.10' - gem 'brakeman', '~> 5.1', '>= 4.6.1', require: false + gem 'brakeman', '~> 6.1', '>= 5.4', require: false gem 'seedbank', '~> 0.5.0' end group :doc do - gem 'sdoc', '~> 2.2.0', require: false + gem 'sdoc', '~> 2.6', require: false end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index a1791957be..68bba718c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -32,16 +32,12 @@ GIT rake GIT - remote: https://github.com/LocoDelAssembly/paperclip.git - revision: 3840d5a63b1a85fb99bfc7c569d132af12a077a1 - branch: migration-fix + remote: https://github.com/LocoDelAssembly/paperclip-meta.git + revision: 31c55c7d914d14460b8907a546bd66287cc22988 + branch: kt-paperclip specs: - paperclip (6.1.0) - activemodel (>= 4.2.0) - activesupport (>= 4.2.0) - mime-types - mimemagic (~> 0.3.0) - terrapin (~> 0.6.0) + paperclip-meta (3.1.0) + kt-paperclip (>= 7.0) GIT remote: https://github.com/LocoDelAssembly/serrano.git @@ -83,74 +79,89 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (1.1.0) - actioncable (6.1.7.7) - actionpack (= 6.1.7.7) - activesupport (= 6.1.7.7) + actioncable (7.1.3.2) + actionpack (= 7.1.3.2) + activesupport (= 7.1.3.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.7) - actionpack (= 6.1.7.7) - activejob (= 6.1.7.7) - activerecord (= 6.1.7.7) - activestorage (= 6.1.7.7) - activesupport (= 6.1.7.7) + zeitwerk (~> 2.6) + actionmailbox (7.1.3.2) + actionpack (= 7.1.3.2) + activejob (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) mail (>= 2.7.1) - actionmailer (6.1.7.7) - actionpack (= 6.1.7.7) - actionview (= 6.1.7.7) - activejob (= 6.1.7.7) - activesupport (= 6.1.7.7) + net-imap + net-pop + net-smtp + actionmailer (7.1.3.2) + actionpack (= 7.1.3.2) + actionview (= 7.1.3.2) + activejob (= 7.1.3.2) + activesupport (= 7.1.3.2) mail (~> 2.5, >= 2.5.4) - rails-dom-testing (~> 2.0) - actionpack (6.1.7.7) - actionview (= 6.1.7.7) - activesupport (= 6.1.7.7) - rack (~> 2.0, >= 2.0.9) + net-imap + net-pop + net-smtp + rails-dom-testing (~> 2.2) + actionpack (7.1.3.2) + actionview (= 7.1.3.2) + activesupport (= 7.1.3.2) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.7) - actionpack (= 6.1.7.7) - activerecord (= 6.1.7.7) - activestorage (= 6.1.7.7) - activesupport (= 6.1.7.7) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.3.2) + actionpack (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.7.7) - activesupport (= 6.1.7.7) + actionview (7.1.3.2) + activesupport (= 7.1.3.2) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.7.7) - activesupport (= 6.1.7.7) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.1.3.2) + activesupport (= 7.1.3.2) globalid (>= 0.3.6) - activemodel (6.1.7.7) - activesupport (= 6.1.7.7) - activerecord (6.1.7.7) - activemodel (= 6.1.7.7) - activesupport (= 6.1.7.7) - activerecord-postgis-adapter (7.1.1) - activerecord (~> 6.1) + activemodel (7.1.3.2) + activesupport (= 7.1.3.2) + activerecord (7.1.3.2) + activemodel (= 7.1.3.2) + activesupport (= 7.1.3.2) + timeout (>= 0.4.0) + activerecord-postgis-adapter (9.0.1) + activerecord (~> 7.1.0) rgeo-activerecord (~> 7.0.0) - activestorage (6.1.7.7) - actionpack (= 6.1.7.7) - activejob (= 6.1.7.7) - activerecord (= 6.1.7.7) - activesupport (= 6.1.7.7) + activestorage (7.1.3.2) + actionpack (= 7.1.3.2) + activejob (= 7.1.3.2) + activerecord (= 7.1.3.2) + activesupport (= 7.1.3.2) marcel (~> 1.0) - mini_mime (>= 1.1.0) - activesupport (6.1.7.7) + activesupport (7.1.3.2) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) minitest (>= 5.1) + mutex_m tzinfo (~> 2.0) - zeitwerk (~> 2.3) acts_as_list (1.1.0) activerecord (>= 4.2) addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) afm (0.2.2) - amazing_print (1.4.0) + amazing_print (1.6.0) asciidoctor (2.0.22) ast (2.4.2) babel-source (5.8.35) @@ -172,7 +183,8 @@ GEM bindex (0.8.1) binding_of_caller (1.0.1) debug_inspector (>= 1.2.0) - brakeman (5.4.1) + brakeman (6.1.2) + racc builder (3.2.4) byebug (11.1.3) capybara (3.40.0) @@ -184,15 +196,15 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - chartkick (4.2.1) + chartkick (5.0.6) chronic (0.10.2) chunky_png (1.4.0) citeproc (1.0.10) namae (~> 1.0) - citeproc-ruby (1.1.14) + citeproc-ruby (2.0.0) citeproc (~> 1.0, >= 1.0.9) - csl (~> 1.6) - climate_control (0.2.0) + csl (~> 2.0) + climate_control (1.2.0) closure_tree (7.4.0) activerecord (>= 4.2.10) with_advisory_lock (>= 4.0.0) @@ -204,15 +216,17 @@ GEM faraday-follow_redirects (>= 0.1, < 0.4) multi_json (~> 1.15) concurrent-ruby (1.2.3) + connection_pool (2.4.1) crack (1.0.0) bigdecimal rexml crass (1.0.6) - csl (1.6.0) + csl (2.0.0) namae (~> 1.0) rexml - csl-styles (1.0.1.11) - csl (~> 1.0) + csl-styles (2.0.1) + csl (~> 2.0) + csv (3.3.0) daemons (1.4.1) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) @@ -230,6 +244,7 @@ GEM diff-lcs (1.5.1) docile (1.4.0) domain_name (0.6.20240107) + drb (2.2.1) dropzonejs-rails (0.8.5) rails (> 3.1) dwc_agent (3.1.1.0) @@ -246,7 +261,7 @@ GEM factory_bot_rails (6.4.3) factory_bot (~> 6.4) railties (>= 5.0.0) - faker (2.23.0) + faker (3.3.1) i18n (>= 1.8.11, < 2) faraday (2.9.0) faraday-net_http (>= 2.0, < 3.2) @@ -265,8 +280,8 @@ GEM activesupport (>= 6.1) gnfinder (1.0.4) rest-client (~> 2.1) - groupdate (5.2.4) - activesupport (>= 5) + groupdate (6.4.0) + activesupport (>= 6.1) guard (2.18.1) formatador (>= 0.2.4) listen (>= 2.7, < 4.0) @@ -292,6 +307,10 @@ GEM concurrent-ruby (~> 1.0) indefinite_article (0.2.5) activesupport + io-console (0.7.2) + irb (1.12.0) + rdoc + reline (>= 0.4.2) jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) @@ -302,7 +321,7 @@ GEM jquery-turbolinks (2.1.0) railties (>= 3.1.0) turbolinks - json (2.7.1) + json (2.7.2) kaminari (1.2.2) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.2) @@ -315,6 +334,12 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) + kt-paperclip (7.2.2) + activemodel (>= 4.2.0) + activesupport (>= 4.2.0) + marcel (~> 1.0.1) + mime-types + terrapin (>= 0.6.0, < 2.0) language_server-protocol (3.17.0.3) latex-decode (0.4.0) link_header (0.0.8) @@ -340,13 +365,11 @@ GEM mime-types (3.5.2) mime-types-data (~> 3.2015) mime-types-data (3.2024.0305) - mimemagic (0.3.10) - nokogiri (~> 1) - rake mini_mime (1.1.5) minitest (5.22.3) modularity (3.0.1) multi_json (1.15.0) + mutex_m (0.2.0) namae (1.2.0) racc (~> 1.7) namecase (2.0.0) @@ -360,10 +383,18 @@ GEM net-protocol net-protocol (0.2.2) timeout - net-smtp (0.3.4) + net-smtp (0.5.0) net-protocol netrc (0.11.0) nio4r (2.7.1) + nokogiri (1.16.3-aarch64-linux) + racc (~> 1.4) + nokogiri (1.16.3-arm-linux) + racc (~> 1.4) + nokogiri (1.16.3-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.3-x86-linux) + racc (~> 1.4) nokogiri (1.16.3-x86_64-darwin) racc (~> 1.4) nokogiri (1.16.3-x86_64-linux) @@ -374,13 +405,11 @@ GEM observer (0.1.2) os (1.1.4) package_json (0.1.0) - paper_trail (12.3.0) - activerecord (>= 5.2) - request_store (~> 1.1) - paperclip-meta (3.1.0) - paperclip (>= 5.0) + paper_trail (15.1.0) + activerecord (>= 6.1) + request_store (~> 1.4) parallel (1.24.0) - parallel_tests (4.6.0) + parallel_tests (4.6.1) parallel parser (3.3.0.5) ast (~> 2.4.1) @@ -407,7 +436,8 @@ GEM pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - psych (3.3.4) + psych (5.1.2) + stringio public_suffix (5.0.5) puma (6.4.2) nio4r (~> 2.0) @@ -417,23 +447,27 @@ GEM rack (>= 2.0.0) rack-proxy (0.7.7) rack + rack-session (1.0.2) + rack (< 3) rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.7) - actioncable (= 6.1.7.7) - actionmailbox (= 6.1.7.7) - actionmailer (= 6.1.7.7) - actionpack (= 6.1.7.7) - actiontext (= 6.1.7.7) - actionview (= 6.1.7.7) - activejob (= 6.1.7.7) - activemodel (= 6.1.7.7) - activerecord (= 6.1.7.7) - activestorage (= 6.1.7.7) - activesupport (= 6.1.7.7) + rackup (1.0.0) + rack (< 3) + webrick + rails (7.1.3.2) + actioncable (= 7.1.3.2) + actionmailbox (= 7.1.3.2) + actionmailer (= 7.1.3.2) + actionpack (= 7.1.3.2) + actiontext (= 7.1.3.2) + actionview (= 7.1.3.2) + activejob (= 7.1.3.2) + activemodel (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) bundler (>= 1.15.0) - railties (= 6.1.7.7) - sprockets-rails (>= 2.0.0) + railties (= 7.1.3.2) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -449,13 +483,15 @@ GEM rails (>= 3.2) rails_or (1.1.9) activerecord (>= 3) - railties (6.1.7.7) - actionpack (= 6.1.7.7) - activesupport (= 6.1.7.7) - method_source + railties (7.1.3.2) + actionpack (= 7.1.3.2) + activesupport (= 7.1.3.2) + irb + rackup (>= 1.0.0) rake (>= 12.2) - thor (~> 1.0) - rainbow (3.0.0) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) rake (13.2.0) rb-fsevent (0.11.2) rb-inotify (0.10.1) @@ -463,10 +499,13 @@ GEM rdf (3.3.1) bcp47_spec (~> 0.2) link_header (~> 0.0, >= 0.0.8) - rdoc (6.3.4.1) + rdoc (6.6.3.1) + psych (>= 4.0.0) redcarpet (3.6.0) redis (4.8.1) regexp_parser (2.9.0) + reline (0.5.0) + io-console (~> 0.5) request_store (1.6.0) rack (>= 1.4) require_all (3.0.0) @@ -516,14 +555,14 @@ GEM rspec-mocks (3.13.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (5.1.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - railties (>= 5.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-rails (6.1.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) rspec-support (3.13.1) rtesseract (3.1.3) rubocop (1.62.1) @@ -577,7 +616,7 @@ GEM sprockets (> 3.0) sprockets-rails tilt - sdoc (2.2.0) + sdoc (2.6.1) rdoc (>= 5.0) seedbank (0.5.0) rake (>= 10.0) @@ -608,29 +647,31 @@ GEM spring (4.1.3) spring-commands-rspec (1.0.4) spring (>= 0.9.1) - sprockets (3.7.3) - base64 + sprockets (4.2.1) concurrent-ruby (~> 1.0) - rack (> 1, < 3) + rack (>= 2.2.4, < 4) sprockets-es6 (0.9.2) babel-source (>= 5.8.11) babel-transpiler sprockets (>= 3.0.0) - sprockets-rails (3.2.2) - actionpack (>= 4.0) - activesupport (>= 4.0) + sprockets-rails (3.4.2) + actionpack (>= 5.2) + activesupport (>= 5.2) sprockets (>= 3.0.0) sqed (0.8.2) rake (~> 13.0) rmagick (~> 5.2) rtesseract (~> 3.1) + stringio (3.1.0) sync (0.5.0) taxonifi (0.6.0) require_all (~> 3.0) term-ansicolor (1.7.2) tins (~> 1.0) - terrapin (0.6.0) - climate_control (>= 0.0.3, < 1.0) + terrapin (1.0.1) + climate_control + terser (1.2.2) + execjs (>= 0.3.0, < 3) thor (1.2.2) tilt (2.3.0) timecop (0.9.8) @@ -649,11 +690,10 @@ GEM concurrent-ruby (~> 1.0) tzinfo-data (1.2024.1) tzinfo (>= 1.0.0) - uglifier (4.2.0) - execjs (>= 0.3.0, < 3) unicode-display_width (2.5.0) uri (0.13.0) - validates_timeliness (4.1.1) + validates_timeliness (7.0.0.beta2) + activemodel (>= 7.0.0, < 8) timeliness (>= 0.3.10, < 1) vcr (6.2.0) waxy (0.1.1) @@ -667,6 +707,7 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) + webrick (1.8.1) websocket (1.2.10) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) @@ -681,20 +722,22 @@ GEM zeitwerk (>= 2.6) xpath (3.2.0) nokogiri (~> 1.8) - zaru (0.3.0) + zaru (1.0.0) zeitwerk (2.6.13) zip_tricks (5.6.0) PLATFORMS - x86_64-darwin-20 - x86_64-darwin-22 - x86_64-darwin-23 + aarch64-linux + arm-linux + arm64-darwin + x86-linux + x86_64-darwin x86_64-linux DEPENDENCIES - activerecord-postgis-adapter (~> 7.0) + activerecord-postgis-adapter (~> 9.0) acts_as_list (~> 1.0) - amazing_print (~> 1.4.0) + amazing_print (~> 1.5) asciidoctor (~> 2.0) barby (~> 0.6.8) bcrypt (~> 3.1.11) @@ -703,19 +746,20 @@ DEPENDENCIES bibtex-ruby (~> 6.0) binding_of_caller biodiversity! - brakeman (~> 5.1, >= 4.6.1) - bundler (~> 2.0) + brakeman (~> 6.1, >= 5.4) + bundler (~> 2.5) byebug (~> 11.1) capybara (~> 3.18) - chartkick (~> 4.0) + chartkick (~> 5.0) chronic (~> 0.10.2) chunky_png (~> 1.4.0) - citeproc-ruby (~> 1.1.10) + citeproc-ruby (~> 2.0) closure_tree (~> 7.0) codecov (~> 0.6.0) colrapi (~> 0.1.1) - csl (~> 1.6.0) - csl-styles (~> 1.0.1.8) + csl (~> 2.0) + csl-styles (~> 2.0.1) + csv (~> 3.2) daemons (~> 1.4.1) database_cleaner (~> 2.0) delayed_job_active_record (~> 4.1.3) @@ -725,11 +769,11 @@ DEPENDENCIES exception_notification (~> 4.4) execjs (~> 2.8.1) factory_bot_rails (~> 6.2) - faker (~> 2.10) + faker (~> 3.2) ffi-geos (~> 2.4.0) gnfinder (~> 1.0) gpx! - groupdate (~> 5.2) + groupdate (~> 6.4) guard-rspec (~> 4.7.3) hiredis (~> 0.6.1) indefinite_article (~> 0.2.4) @@ -738,17 +782,17 @@ DEPENDENCIES jquery-turbolinks (~> 2.1) jquery-ui-rails! kaminari (~> 1.2.0) + kt-paperclip (~> 7.2) logic_tools logical_query_parser mail (~> 2.8, >= 2.8.1) matrix (~> 0.4.2) modularity (~> 3.0.0) namecase (~> 2.0) - net-smtp (~> 0.3.1) + net-smtp (~> 0.4) os (~> 1.0, >= 1.0.1) - paper_trail (~> 12.0) - paperclip! - paperclip-meta (~> 3.0) + paper_trail (~> 15.0) + paperclip-meta! parallel (~> 1.23) parallel_tests passenger (~> 6.0.2) @@ -756,14 +800,14 @@ DEPENDENCIES pg (~> 1.1) postgresql_cursor (~> 0.6.1) prawn (~> 2.4.0) - psych (~> 3.3) + psych (~> 5.1) puma (~> 6.3) rack-cors (~> 2.0) - rails (~> 6.1) + rails (~> 7.1) rails-controller-testing (~> 1.0.2) rails-jquery-autocomplete (~> 1.0.3) rails_or (~> 1.1.8) - rainbow (~> 3.0.0) + rainbow (~> 3.0) rake (~> 13.0) rdf (~> 3.0) redcarpet (~> 3.4) @@ -779,7 +823,7 @@ DEPENDENCIES rqrcode! rspec (~> 3.6) rspec-activemodel-mocks (~> 1.1.0) - rspec-rails (~> 5.0) + rspec-rails (~> 6.1) rubocop (~> 1.20) rubocop-faker (~> 1.1) rubocop-performance (~> 1.10) @@ -791,37 +835,37 @@ DEPENDENCIES ruby-units (~> 2.3.0) rubyzip (~> 2.3.0) sassc-rails (~> 2.1.0) - sdoc (~> 2.2.0) + sdoc (~> 2.6) seedbank (~> 0.5.0) selenium-webdriver (~> 4.6, >= 4.6.1) serrano! shakapacker (= 7.2.3) - shortener (~> 1.0.0) + shortener (~> 1.0) simplecov spring-commands-rspec (~> 1.0.4) - sprockets (~> 3.7.2) + sprockets (~> 4.2) sprockets-es6 (~> 0.9.2) - sprockets-rails (~> 3.2.0) + sprockets-rails (~> 3.4.0) sqed (~> 0.8.1) taxonifi (~> 0.6.0) term-ansicolor (~> 1.6) + terser (~> 1.2) thor (~> 1.2) timecop (~> 0.9.1) turbolinks (~> 5.2.0) tzinfo-data (~> 1.2019) - uglifier (~> 4.2) - validates_timeliness (~> 4.1, >= 4.1.1) + validates_timeliness (~> 7.0.0.beta2) vcr (~> 6.0) voight_kampff! waxy (~> 0.1.1) web-console (~> 4.0, >= 4.0.1) webmock (~> 3.8) wikidata-client (~> 0.1.0.pre.rc1) - zaru (~> 0.3.0) + zaru (~> 1.0) zip_tricks (~> 5.6) RUBY VERSION - ruby 3.2.1p31 + ruby 3.3.0p0 BUNDLED WITH - 2.4.10 + 2.5.3 diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js new file mode 100644 index 0000000000..b16e53d6d5 --- /dev/null +++ b/app/assets/config/manifest.js @@ -0,0 +1,3 @@ +//= link_tree ../images +//= link_directory ../javascripts .js +//= link_directory ../stylesheets .css diff --git a/app/controllers/api/v1/cite_controller.rb b/app/controllers/api/v1/cite_controller.rb index 49de662af9..a2c153b6c3 100644 --- a/app/controllers/api/v1/cite_controller.rb +++ b/app/controllers/api/v1/cite_controller.rb @@ -1,4 +1,3 @@ -require 'taxon_names_helper.rb' class Api::V1::CiteController < ApiController def count_valid_species diff --git a/app/controllers/dataset_records_controller.rb b/app/controllers/dataset_records_controller.rb index 9bbe6f0ff5..9b72993a8f 100644 --- a/app/controllers/dataset_records_controller.rb +++ b/app/controllers/dataset_records_controller.rb @@ -110,7 +110,7 @@ def filtered_records dataset_records = import_dataset.core_records params[:filter]&.each do |key, value| dataset_records = dataset_records.where( - id: import_dataset.core_records_fields.at(key.to_i).with_value(value).select(:dataset_record_id) + id: import_dataset.core_records_fields.at(key.to_i).having_value(value).select(:dataset_record_id) ) end diff --git a/app/models/citation.rb b/app/models/citation.rb index b896e907ab..68d3e8cf75 100644 --- a/app/models/citation.rb +++ b/app/models/citation.rb @@ -49,8 +49,9 @@ class Citation < ApplicationRecord has_many :documents, through: :source validates_presence_of :source + validates_uniqueness_of :source_id, scope: [:citation_object_id, :citation_object_type, :pages] - validates_uniqueness_of :is_original, scope: [:citation_object_type, :citation_object_id], message: 'origin can only be assigned once', allow_nil: true, if: :is_original? + validates_uniqueness_of :is_original, scope: [:citation_object_type, :citation_object_id], message: 'origin can only be assigned once', allow_nil: true, if: -> { is_original? } accepts_nested_attributes_for :citation_topics, allow_destroy: true, reject_if: :reject_citation_topics accepts_nested_attributes_for :topics, allow_destroy: true, reject_if: :reject_topic diff --git a/app/models/concerns/shared/citations.rb b/app/models/concerns/shared/citations.rb index 438d72be25..07d3893572 100644 --- a/app/models/concerns/shared/citations.rb +++ b/app/models/concerns/shared/citations.rb @@ -100,7 +100,7 @@ module Shared::Citations accepts_nested_attributes_for :citations, reject_if: :reject_citations, allow_destroy: true accepts_nested_attributes_for :origin_citation, reject_if: :reject_citations, allow_destroy: true - validate :origin_citation_source_id, if: -> {!new_record?} + validate :origin_citation_source_id, if: -> { !new_record? } # !! use validate: true in associations settings to trigger this as needed # Required to trigger validate callbacks, which in turn set user_id related housekeeping diff --git a/app/models/concerns/shared/polymorphic_annotator.rb b/app/models/concerns/shared/polymorphic_annotator.rb index 0e9d11ebd1..7b7ad7a460 100644 --- a/app/models/concerns/shared/polymorphic_annotator.rb +++ b/app/models/concerns/shared/polymorphic_annotator.rb @@ -46,6 +46,8 @@ def related_klasses included do + attr_accessor :annotated_object + # Concern implementation macro # # @param foreign_key [String, nil] @@ -64,7 +66,8 @@ def self.polymorphic_annotates(polymorphic_belongs, foreign_key: nil, inverse_of belongs_to(polymorphic_belongs.to_sym, polymorphic: true, foreign_key: (foreign_key.nil? ? (polymorphic_belongs.to_s + '_id').to_s : polymorphic_belongs.to_s), inverse_of:) - alias_attribute :annotated_object, polymorphic_belongs.to_sym + alias_method :annotated_object, polymorphic_belongs.to_sym + alias_method :annotated_object=, (polymorphic_belongs.to_s + '=').to_sym define_singleton_method(:annotator_reflection){polymorphic_belongs.to_s} diff --git a/app/models/dataset_record/darwin_core/taxon.rb b/app/models/dataset_record/darwin_core/taxon.rb index 78a4b33c37..2dc12de91b 100644 --- a/app/models/dataset_record/darwin_core/taxon.rb +++ b/app/models/dataset_record/darwin_core/taxon.rb @@ -155,6 +155,7 @@ def import(dwc_data_attributes = {}) metadata: }) + taxon_name.save! end # make OC relationships to OC ancestors @@ -205,7 +206,6 @@ def import(dwc_data_attributes = {}) !taxon_name.year_integer.nil? && ancestor_protonym.year_integer > taxon_name.year_integer - taxon_name.save! TaxonNameRelationship.find_or_create_by!(type: rank_in_type, subject_taxon_name: ancestor_protonym, object_taxon_name: taxon_name) end end @@ -223,7 +223,7 @@ def import(dwc_data_attributes = {}) # get OC dataset_record_id so we can pull the taxonRank from it. oc_dataset_record_id = import_dataset.core_records_fields .at(get_field_mapping(:taxonID)) - .with_value(get_field_value(:originalNameUsageID)) + .having_value(get_field_value(:originalNameUsageID)) .pick(:dataset_record_id) oc_protonym_rank = import_dataset.core_records_fields @@ -579,7 +579,7 @@ def create_parent_element_hash def get_parent DatasetRecord::DarwinCore::Taxon.where(id: import_dataset.core_records_fields .at(get_field_mapping(:taxonID)) - .with_value(get_field_value(:parentNameUsageID)) + .having_value(get_field_value(:parentNameUsageID)) .select(:dataset_record_id) ).first end @@ -588,7 +588,7 @@ def get_parent def get_original_combination DatasetRecord::DarwinCore::Taxon.where(id: import_dataset.core_records_fields .at(get_field_mapping(:taxonID)) - .with_value(get_field_value(:originalNameUsageID)) + .having_value(get_field_value(:originalNameUsageID)) .select(:dataset_record_id) ).first end @@ -597,7 +597,7 @@ def get_original_combination def find_by_taxonID(taxon_id) DatasetRecord::DarwinCore::Taxon.where(id: import_dataset.core_records_fields .at(get_field_mapping(:taxonID)) - .with_value(taxon_id.to_s) + .having_value(taxon_id.to_s) .select(:dataset_record_id) ).first end @@ -606,7 +606,7 @@ def find_by_taxonID(taxon_id) def get_taxon_name_from_taxon_id(taxon_id) TaxonName.find(DatasetRecord::DarwinCore::Taxon.where(id: import_dataset.core_records_fields .at(get_field_mapping(:taxonID)) - .with_value(taxon_id.to_s) + .having_value(taxon_id.to_s) .select(:dataset_record_id) ).pick(:metadata)['imported_objects']['taxon_name']['id']) end @@ -615,13 +615,13 @@ def get_taxon_name_from_taxon_id(taxon_id) def dependencies_imported?(taxon_id) dependency_taxon_ids = DatasetRecord::DarwinCore::Taxon.where(id: import_dataset.core_records_fields .at(get_field_mapping(:taxonID)) - .with_value(taxon_id.to_s) + .having_value(taxon_id.to_s) .select(:dataset_record_id) ).pick(:metadata)['dependencies'] DatasetRecord::DarwinCore::Taxon.where(id: import_dataset.core_records_fields .at(get_field_mapping(:taxonID)) - .with_values(dependency_taxon_ids.map { |d| d.to_s }) + .having_values(dependency_taxon_ids.map { |d| d.to_s }) .select(:dataset_record_id) ).where(status: 'Imported').count == dependency_taxon_ids.length diff --git a/app/models/dataset_record_field.rb b/app/models/dataset_record_field.rb index bece2bb41d..0886c1a7f5 100644 --- a/app/models/dataset_record_field.rb +++ b/app/models/dataset_record_field.rb @@ -20,13 +20,13 @@ def self.at(position) where(position: position) end - def self.with_value(value) + def self.having_value(value) where(indexed_column_value(value).eq(value)) end # Messy way of passing array of values for indexed_column_value # @param [Array] values - def self.with_values(values) + def self.having_values(values) if values.all? { |value| !value.nil? && value.length < VALUE_INDEX_LIMIT} where(indexed_column_value(values.first).in(values)) else diff --git a/app/models/document.rb b/app/models/document.rb index e4ed96df73..b5930bfda5 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -57,8 +57,9 @@ class Document < ApplicationRecord accepts_nested_attributes_for :documentation, allow_destroy: true, reject_if: :reject_documentation + # TODO: Remove on ActiveStorage before_save :set_pdf_metadata, if: -> { - ActiveSupport::Deprecation.silence do + Rails.application.deprecators.silence do changed_attributes.include?('document_file_file_size') && document_file_content_type =~ /pdf/ end diff --git a/app/models/import_dataset/darwin_core.rb b/app/models/import_dataset/darwin_core.rb index 65741c8d33..d45d77654e 100644 --- a/app/models/import_dataset/darwin_core.rb +++ b/app/models/import_dataset/darwin_core.rb @@ -342,7 +342,7 @@ def destroy_namespace def add_filters(records, filters) filters&.each do |key, value| - records = records.where(id: core_records_fields.at(key.to_i).with_value(value).select(:dataset_record_id)) + records = records.where(id: core_records_fields.at(key.to_i).having_value(value).select(:dataset_record_id)) end records end diff --git a/app/models/import_dataset/darwin_core/occurrences.rb b/app/models/import_dataset/darwin_core/occurrences.rb index 069f0b43dd..f4134dd20f 100644 --- a/app/models/import_dataset/darwin_core/occurrences.rb +++ b/app/models/import_dataset/darwin_core/occurrences.rb @@ -145,7 +145,7 @@ def update_catalog_number_namespace(institution_code, collection_code, namespace # TODO: Add scopes/methods in DatasetRecord to handle nil fields values transparently unless institution_code.nil? query = query.where( - id: core_records_fields.at(get_field_mapping(:institutionCode)).with_value(institution_code).select(:dataset_record_id) + id: core_records_fields.at(get_field_mapping(:institutionCode)).having_value(institution_code).select(:dataset_record_id) ) else query = query.where.not( @@ -154,7 +154,7 @@ def update_catalog_number_namespace(institution_code, collection_code, namespace end unless collection_code.nil? query = query.where( - id: core_records_fields.at(get_field_mapping(:collectionCode)).with_value(collection_code).select(:dataset_record_id) + id: core_records_fields.at(get_field_mapping(:collectionCode)).having_value(collection_code).select(:dataset_record_id) ) else query = query.where.not( @@ -182,16 +182,16 @@ def update_catalog_number_collection_code_namespace(collection_code, namespace_i if ready query.where( - id: core_records_fields.at(get_field_mapping(:collectionCode)).with_value(collection_code).select(:dataset_record_id) + id: core_records_fields.at(get_field_mapping(:collectionCode)).having_value(collection_code).select(:dataset_record_id) ).update_all( "status = 'Ready', metadata = metadata - 'error_data'" ) else institution_codes = self.metadata["catalog_numbers_namespaces"]&.select { |m| m[0][1] == collection_code && m[1] }&.map { |m| m[0][0] } || [] query.where( - id: core_records_fields.at(get_field_mapping(:collectionCode)).with_value(collection_code).select(:dataset_record_id) + id: core_records_fields.at(get_field_mapping(:collectionCode)).having_value(collection_code).select(:dataset_record_id) ).where.not( - id: core_records_fields.at(get_field_mapping(:institutionCode)).with_values(institution_codes).select(:dataset_record_id) + id: core_records_fields.at(get_field_mapping(:institutionCode)).having_values(institution_codes).select(:dataset_record_id) ).update_all( "status = 'NotReady', metadata = jsonb_set(metadata, '{error_data}', '{ \"messages\": { \"catalogNumber\": [\"Record cannot be imported until namespace is set, see \\\"Settings\\\".\"] } }')" ) diff --git a/app/models/protonym.rb b/app/models/protonym.rb index e547f07592..aa5184c640 100644 --- a/app/models/protonym.rb +++ b/app/models/protonym.rb @@ -39,8 +39,6 @@ class Protonym < TaxonName :verbatim_author_without_digits, :verbatim_author_with_closed_parens_when_present - after_create :create_otu, if: -> {self.also_create_otu} - has_one :type_taxon_name_relationship, -> { where("taxon_name_relationships.type LIKE 'TaxonNameRelationship::Typification::%'") }, class_name: 'TaxonNameRelationship', foreign_key: :object_taxon_name_id @@ -973,10 +971,6 @@ def name_is_valid_format rank_class.validate_name_format(self) if name.present? && rank_class && rank_class.respond_to?(:validate_name_format) && !has_latinized_exceptions? end - def create_otu - Otu.create(by: self.creator, project: self.project, taxon_name_id: self.id) - end - def new_parent_taxon_name r = self.iczn_uncertain_placement_relationship if r.present? @@ -1056,8 +1050,9 @@ def sv_cached_names # this cannot be moved to soft_validation_extensions end def set_cached - old_cached_html = cached_html.to_s - old_cached_author_year = cached_author_year.to_s + # old_cached_html = cached_html.to_s + old_cached_author_year = cached_author_year.to_s # why to_s? + old_cached = cached.to_s # why to_s? super set_cached_original_combination @@ -1066,8 +1061,8 @@ def set_cached set_cached_species_homonym if is_species_rank? set_cached_misspelling tn = TaxonName.find(id) - set_cached_names_for_descendants if tn.cached_html != old_cached_html - set_cached_names_for_dependants if tn.cached_html.to_s != old_cached_html || tn.cached_author_year.to_s != old_cached_author_year + set_cached_names_for_descendants if tn.cached != old_cached + set_cached_names_for_dependants if tn.cached.to_s != old_cached || tn.cached_author_year.to_s != old_cached_author_year end def set_cached_homonymy diff --git a/app/models/role.rb b/app/models/role.rb index dd9864da5d..df89b81d54 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -130,7 +130,8 @@ def set_cached end def set_role_object_cached - becomes(type.constantize).cached_trigger_methods(role_object).each do |m| + a = self.dup + a.becomes(type.constantize).cached_trigger_methods(role_object).each do |m| role_object.send(m) unless role_object.destroyed? end end @@ -159,26 +160,26 @@ def cached_trigger_methods(object) # # Person only roles -require_dependency 'taxon_name_author' -require_dependency 'source_source' -require_dependency 'source_author' -require_dependency 'source_editor' -require_dependency 'collector' -require_dependency 'georeferencer' -require_dependency 'loan_recipient' -require_dependency 'loan_supervisor' - -# Records below have not been hooked to Person activity years - -require_dependency 'accession_provider' -require_dependency 'deaccession_recipient' -require_dependency 'verifier' - -# TODO: these are being used in Attribution, or not? -require_dependency 'attribution_creator' -require_dependency 'attribution_editor' - -# Person OR Organization roles -require_dependency 'attribution_copyright_holder' -require_dependency 'attribution_owner' -require_dependency 'determiner' +# require_dependency 'taxon_name_author' +# require_dependency 'source_source' +# require_dependency 'source_author' +# require_dependency 'source_editor' +# require_dependency 'collector' +# require_dependency 'georeferencer' +# require_dependency 'loan_recipient' +# require_dependency 'loan_supervisor' + +# # Records below have not been hooked to Person activity years + +# require_dependency 'accession_provider' +# require_dependency 'deaccession_recipient' +# require_dependency 'verifier' + +# # TODO: these are being used in Attribution, or not? +# require_dependency 'attribution_creator' +# require_dependency 'attribution_editor' + +# # Person OR Organization roles +# require_dependency 'attribution_copyright_holder' +# require_dependency 'attribution_owner' +# require_dependency 'determiner' diff --git a/app/models/sqed_depiction.rb b/app/models/sqed_depiction.rb index bc93cbe27d..73c2d71a7a 100644 --- a/app/models/sqed_depiction.rb +++ b/app/models/sqed_depiction.rb @@ -46,7 +46,7 @@ class SqedDepiction < ApplicationRecord belongs_to :depiction has_one :image, through: :depiction - has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object + has_one :collection_object, through: :depiction, source_type: 'CollectionObject', source: :depiction_object, inverse_of: :sqed_depictions validates_presence_of :depiction validates_presence_of :metadata_map, :boundary_color diff --git a/app/models/taxon_name.rb b/app/models/taxon_name.rb index 2bc6b4f690..335ea7e2a1 100644 --- a/app/models/taxon_name.rb +++ b/app/models/taxon_name.rb @@ -206,34 +206,25 @@ def self.parent # to a new cached value, so let's record the old one # after_save :create_new_combination_if_absent - after_save :set_cached, unless: Proc.new {|n| n.no_cached || errors.any? } - after_save :set_cached_warnings, if: Proc.new {|n| n.no_cached } after_create :create_otu, if: :also_create_otu before_destroy :check_for_children, prepend: true - validate :validate_rank_class_class, - # :check_format_of_name, - :validate_parent_from_the_same_project, - :validate_parent_is_set, - :check_new_rank_class, - :check_new_parent_class, - :validate_source_type, - :validate_one_root_per_project - - # TODO: remove, this is handled natively - validates_presence_of :type, message: 'is not specified' + # Rails 7 experiments have after_commit creating a whack-a-mole situation + # (though leave after_commit on TaxonNameRelationship) + after_save :set_cached, unless: Proc.new {|n| n.no_cached || errors.any? } + after_save :set_cached_warnings, if: Proc.new {|n| n.no_cached } + validate :validate_rank_class_class + validate :check_new_rank_class + validate :check_new_parent_class + validate :validate_source_type + validate :validate_parent_from_the_same_project + validate :validate_one_root_per_project + validates_presence_of :type, message: 'is not specified' # TODO: remove, this is handled natively, and in DB validates :year_of_publication, date_year: {min_year: 1000, max_year: Time.now.year + 5}, allow_nil: true # TODO: move some of these down to Protonym when they don't apply to Combination - # TODO: think of a different name, and test - has_many :historical_taxon_names, class_name: 'TaxonName', foreign_key: :cached_valid_taxon_name_id - - has_many :observation_matrix_row_items, as: :observation_object, inverse_of: :observation_object, class_name: 'ObservationMatrixRowItem::Dynamic::TaxonName', dependent: :destroy # was delete_all - has_many :observation_matrices, through: :observation_matrix_row_items - - # TODO: revisit? belongs_to :valid_taxon_name, class_name: 'TaxonName', foreign_key: :cached_valid_taxon_name_id has_one :source_classified_as_relationship, -> { @@ -246,6 +237,12 @@ def self.parent has_one :source_classified_as, through: :source_classified_as_relationship, source: :object_taxon_name + # TODO: think of a different name, and test + has_many :historical_taxon_names, class_name: 'TaxonName', foreign_key: :cached_valid_taxon_name_id + + has_many :observation_matrix_row_items, as: :observation_object, inverse_of: :observation_object, class_name: 'ObservationMatrixRowItem::Dynamic::TaxonName', dependent: :destroy # was delete_all + has_many :observation_matrices, through: :observation_matrix_row_items + has_many :otus, inverse_of: :taxon_name, dependent: :restrict_with_error has_many :taxon_determinations, through: :otus @@ -261,7 +258,6 @@ def self.parent has_many :taxon_name_classifications, dependent: :destroy, inverse_of: :taxon_name has_many :taxon_name_relationships, foreign_key: :subject_taxon_name_id, dependent: :restrict_with_error, inverse_of: :subject_taxon_name - # NOTE: Protonym subclassed methods might not be nicely tracked here, we'll have to see. Placement is after has_many relationships. (?) accepts_nested_attributes_for :related_taxon_name_relationships, allow_destroy: true, reject_if: proc { |attributes| attributes['type'].blank? || attributes['subject_taxon_name_id'].blank? } accepts_nested_attributes_for :family_group_name_form_relationship, allow_destroy: true, reject_if: proc { |attributes| attributes['object_taxon_name_id'].blank? } @@ -979,13 +975,15 @@ def first_possible_valid_taxon_name # returns list of invalid names for a given taxon. # Can't we just use #valid_id now? # DD: no this is used for validation of multiple conflicting relationships - # this list does not return combinations + # this list does not return Combinations def list_of_invalid_taxon_names first_pass = true list = {} while first_pass || !list.keys.select{|t| list[t] == false}.empty? do first_pass = false + list_of_taxa_to_check = list.empty? ? [self] : list.keys.select{|t| list[t] == false} + list_of_taxa_to_check.each do |t| potentialy_invalid_relationships = t.related_taxon_name_relationships.with_type_array(::TAXON_NAME_RELATIONSHIP_NAMES_SYNONYM).order_by_oldest_source_first potentialy_invalid_relationships.each do |r| @@ -999,7 +997,7 @@ def list_of_invalid_taxon_names end end return [] if list.empty? - list.sort_by{|t, a| (t.cached_nomenclature_date&.to_time || Time.now)}.collect{|t, a| t} + list.sort_by{|t, a| (t.cached_nomenclature_date&.to_time || Time.zone.now)}.collect{|t, a| t} end def gbif_status_array @@ -1485,11 +1483,6 @@ def get_cached_classified_as nil end - # @return [Boolean] - def parent_is_set? - !parent_id.nil? || (parent&.persisted?) - end - # TODO: this should be paginated, not all IDs! def next_sibling if siblings.where(project_id:).any? @@ -1645,10 +1638,9 @@ def check_for_children end end - def validate_parent_is_set - if !(rank_class == NomenclaturalRank) && !(type == 'Combination') - errors.add(:parent_id, 'is not selected') if !parent_is_set? - end + # @return [Boolean] + def parent_is_set? + parent_id.present? || parent # &.persisted? end def validate_parent_from_the_same_project diff --git a/app/models/taxon_name_relationship.rb b/app/models/taxon_name_relationship.rb index 9868ae692d..6f63dc468e 100644 --- a/app/models/taxon_name_relationship.rb +++ b/app/models/taxon_name_relationship.rb @@ -55,25 +55,19 @@ class TaxonNameRelationship < ApplicationRecord belongs_to :subject_taxon_name, class_name: 'TaxonName', inverse_of: :taxon_name_relationships # left side belongs_to :object_taxon_name, class_name: 'TaxonName', inverse_of: :related_taxon_name_relationships # right side - #has_one :family_group_name_form_relationship, -> {where(type: 'TaxonNameRelationship::Iczn::Invalidating::Usage::FamilyGroupNameForm')}, as: :subject_taxon_name, class_name: 'TaxonNameRelationship', inverse_of: :subject_taxon_name - - after_save :set_cached_names_for_taxon_names, unless: -> {self.no_cached} + # !! Keep as after_commit unless you are wanting to spend a lot of time + # !! refactoring tests + after_commit :set_cached_names_for_taxon_names, unless: -> {self.no_cached || destroyed?} after_destroy :set_cached_names_for_taxon_names, unless: -> {self.no_cached} # TODO: remove, it's required by STI validates_presence_of :type, message: 'Relationship type should be specified' - validates_presence_of :subject_taxon_name, message: 'Missing taxon name on the left side' validates_presence_of :object_taxon_name, message: 'Missing taxon name on the right side' - - validates_associated :subject_taxon_name - validates_associated :object_taxon_name - validates_uniqueness_of :object_taxon_name_id, scope: [:type, :project_id], if: :is_combination? validates_uniqueness_of :object_taxon_name_id, scope: [:type, :subject_taxon_name_id, :project_id], unless: :is_combination? validate :validate_type, :validate_subject_and_object_are_not_identical - validate :subject_and_object_in_same_project with_options unless: -> {!subject_taxon_name || !object_taxon_name} do @@ -330,7 +324,9 @@ def is_combination? def subject_and_object_in_same_project if subject_taxon_name && object_taxon_name - errors.add(:base, 'one name is not in the same project as the other') if subject_taxon_name.project_id != object_taxon_name.project_id + if subject_taxon_name.project_id != object_taxon_name.project_id + errors.add(:base, 'one name is not in the same project as the other') + end end end @@ -433,50 +429,59 @@ def validate_object_and_subject_both_protonyms end def set_cached_names_for_taxon_names - begin - TaxonName.transaction do - if is_invalidating? - t = subject_taxon_name - - if type_name =~/Misspelling/ - t.update_column(:cached_misspelling, t.get_cached_misspelling) - t.update_columns( - cached_author_year: t.get_author_and_year, - cached_nomenclature_date: t.nomenclature_date, - cached_original_combination: t.get_original_combination, - cached_original_combination_html: t.get_original_combination_html - ) - end + # !! only fire if subject_taxon_name changed + return true unless subject_taxon_name_id_previously_changed? || destroyed? - if type_name =~/Misapplication/ - t.update_columns( - cached_author_year: t.get_author_and_year, - cached_nomenclature_date: t.nomenclature_date) - end + TaxonName.transaction do + if is_invalidating? + t = subject_taxon_name - vn = t.get_valid_taxon_name + if type_name =~/Misspelling/ + t.update_column(:cached_misspelling, t.get_cached_misspelling) + t.update_columns( + cached_author_year: t.get_author_and_year, + cached_nomenclature_date: t.nomenclature_date, + cached_original_combination: t.get_original_combination, + cached_original_combination_html: t.get_original_combination_html) + end - n = t.get_full_name + if type_name =~/Misapplication/ t.update_columns( - cached: n, - cached_html: t.get_full_name_html(n), # OK to force reload here, otherwise we need an exception in #set_cached + cached_author_year: t.get_author_and_year, + cached_nomenclature_date: t.nomenclature_date) + end + + vn = t.get_valid_taxon_name + + # !! NO set cached should do this from TN side of things, + # !! Not here + + n = t.get_full_name + + t.update_columns( + cached: n, + cached_html: t.get_full_name_html(n), # OK to force reload here, otherwise we need an exception in #set_cached + cached_valid_taxon_name_id: vn.id, + cached_is_valid: !t.unavailable_or_invalid?) + + t.combination_list_self.each do |c| + c.update_column(:cached_valid_taxon_name_id, vn.id) + end + + vn.list_of_invalid_taxon_names.each do |s| + s.update_columns( cached_valid_taxon_name_id: vn.id, - cached_is_valid: !t.unavailable_or_invalid?) - t.combination_list_self.each do |c| - c.update_column(:cached_valid_taxon_name_id, vn.id) - end + cached_is_valid: !s.unavailable_or_invalid?) - vn.list_of_invalid_taxon_names.each do |s| - s.update_columns( - cached_valid_taxon_name_id: vn.id, - cached_is_valid: !s.unavailable_or_invalid?) - s.combination_list_self.each do |c| - c.update_column(:cached_valid_taxon_name_id, vn.id) - end + s.combination_list_self.each do |c| + c.update_column(:cached_valid_taxon_name_id, vn.id) end end + end + end + true end @@ -673,7 +678,7 @@ def sv_fix_combination_relationship @@subclasses_preloaded = false def self.descendants unless @@subclasses_preloaded - Dir.glob("#{Rails.root}/app/models/taxon_name_relationship/**/*.rb") + Dir.glob("#{Rails.root.join("app/models/taxon_name_relationship/**/*.rb")}") .sort { |a, b| a.split('/').count <=> b.split('/').count } .map { |p| p.split('/app/models/').last.sub(/\.rb$/, '') } .map { |p| p.split('/') } diff --git a/app/models/taxon_name_relationship/combination.rb b/app/models/taxon_name_relationship/combination.rb index e53d2042d2..cef55a65ce 100644 --- a/app/models/taxon_name_relationship/combination.rb +++ b/app/models/taxon_name_relationship/combination.rb @@ -66,12 +66,9 @@ def object_status_connector_to_subject protected def set_cached_names_for_taxon_names - begin - TaxonName.transaction do - t = object_taxon_name - t.send(:set_cached) - end - end + t = object_taxon_name + return true if t.destroyed? # Are we sure this is right? + t.send(:set_cached) true end diff --git a/app/models/taxon_name_relationship/original_combination.rb b/app/models/taxon_name_relationship/original_combination.rb index b2bf2e762b..e14bcff6c8 100644 --- a/app/models/taxon_name_relationship/original_combination.rb +++ b/app/models/taxon_name_relationship/original_combination.rb @@ -62,7 +62,7 @@ def monominal_prefix # TODO: reconcile this format with that of full_name_hash def combination_name(name_gender = nil) elements = [monominal_prefix] - if !subject_taxon_name.verbatim_name.blank? && name_gender.nil? + if subject_taxon_name.verbatim_name.present? && name_gender.nil? elements.push subject_taxon_name.verbatim_name else elements.push subject_taxon_name.genderized_name(name_gender) @@ -82,15 +82,18 @@ def combination_name(name_gender = nil) protected def set_cached_names_for_taxon_names + begin TaxonName.transaction do t = object_taxon_name t.send(:set_cached) - t.update_columns( - cached_original_combination: t.get_original_combination, - cached_original_combination_html: t.get_original_combination_html, - cached_author_year: t.get_author_and_year, - ) + t.send(:set_cached_original_combination) + t.send(:set_cached_original_combination_html) +# t.update_columns( +# cached_original_combination: t.get_original_combination, +# cached_original_combination_html: t.get_original_combination_html, +# # cached_author_year: t.get_author_and_year, # is done in set_cached!! +# ) end end true diff --git a/config/application.rb b/config/application.rb index a85790e547..72c6265372 100644 --- a/config/application.rb +++ b/config/application.rb @@ -13,6 +13,40 @@ class Application < Rails::Application # This breaks housekeeping when on but might be needed # config.load_defaults 6.1 + config.load_defaults 7.1 + + # TODO: confirm 7.1 settings are meaningful + config.active_record.belongs_to_required_by_default = false + + # TODO: remove after testing + # With no settings set: +# config.action_controller.allow_deprecated_parameters_hash_equality = nil +# config.action_dispatch.debug_exception_log_level = :fatal # (not :error) +# config.action_text.sanitizer_vendor = nil +# config.active_job.use_big_decimal_serializer = nil +# config.active_record.allow_deprecated_singular_associations_name = nil +# config.active_record.before_committed_on_all_records = nil +# config.active_record.belongs_to_required_validates_foreign_key = false # false # !! false in 7.1 +# config.active_record.commit_transaction_on_non_local_return = nil +# config.active_record.default_column_serializer = nil +# config.active_record.encryption.hash_digest_class = nil +# config.active_record.encryption.support_sha1_for_non_deterministic_encryption = nil +# config.active_record.generate_secure_token_on = :create # !! (is :initialize in 7.1) +# config.active_record.marshalling_format_version = nil +# config.active_record.query_log_tags_format = :legacy # !! (is :sqlcommenter in 7.1) +# config.active_record.raise_on_assign_to_attr_readonly = false # !! (is true in 7.1) +# config.active_record.run_after_transaction_callbacks_in_order_defined = nil # (true in 7.1) +# config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = nil # (false in 7.1) +# config.active_record.sqlite3_adapter_strict_strings_by_default = nil +# config.active_support.cache_format_version = nil +# config.active_support.message_serializer = nil +# config.active_support.raise_on_invalid_cache_expiration_time = nil +# config.active_support.use_message_serializer_for_metadata = nil +# config.add_autoload_paths_to_load_path = true # !! (this must be it, false in 7.1) +# config.dom_testing_default_html_version = :html4 # !! (Nokogiri/HTML 5 options here) +# config.precompile_filter_parameters = nil + + # Via https://github.com/matthuhiggins/foreigner/pull/95 # config.before_initialize do # Foreigner::Adapter.register 'postgis', 'foreigner/connection_adapters/postgresql_adapter' diff --git a/config/environments/production.rb b/config/environments/production.rb index 3a7258ad16..68bad4eca0 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -29,7 +29,7 @@ config.serve_static_files = false # true # was false until oct/2014 # Compress JavaScripts and CSS. - config.assets.js_compressor = Uglifier.new(harmony: true) + config.assets.js_compressor = :terser # config.assets.css_compressor = :sass # Do not fallback to assets pipeline if a precompiled asset is missed. diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index d5b684fc4d..6e4f8fb9f7 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,7 +1,7 @@ # Be sure to restart your server when you modify this file. TaxonWorks::Application.config.session_store( - :cookie_store, + :cookie_store, key: '_TaxonWorks_session', - expire_after: (Rails.env.to_s == 'production' ? 24.hours : 14.days) + expire_after: (Rails.env.production? ? 24.hours : 14.days) ) diff --git a/config/initializers/silence_deprecations.rb b/config/initializers/silence_deprecations.rb index e9ca025136..e28de76759 100644 --- a/config/initializers/silence_deprecations.rb +++ b/config/initializers/silence_deprecations.rb @@ -1,5 +1,5 @@ -current_behavior = ActiveSupport::Deprecation.behavior -ActiveSupport::Deprecation.behavior = lambda do |message, callstack, deprecation_horizon, gem_name| - return if message =~ /`serialized_attributes` is deprecated without replacement/ && callstack.any? { |m| m =~ /paper_trail/ } - Array.wrap(current_behavior).each { |behavior| behavior.call(message, callstack, deprecation_horizon, gem_name) } -end +# current_behavior = ActiveSupport::Deprecation.behavior +# ActiveSupport::Deprecation.behavior = lambda do |message, callstack, deprecation_horizon, gem_name| +# return if message =~ /`serialized_attributes` is deprecated without replacement/ && callstack.any? { |m| m =~ /paper_trail/ } +# Array.wrap(current_behavior).each { |behavior| behavior.call(message, callstack, deprecation_horizon, gem_name) } +# end diff --git a/db/migrate/20130101000000_postgis_extend.rb b/db/migrate/20130101000000_postgis_extend.rb index c7e31e5733..e7dab45512 100644 --- a/db/migrate/20130101000000_postgis_extend.rb +++ b/db/migrate/20130101000000_postgis_extend.rb @@ -1,7 +1,6 @@ class PostgisExtend < ActiveRecord::Migration[4.2] def change - # Deprecated. This is not needed when rake db:setup is used - # ActiveRecord::Base.connection.execute('CREATE EXTENSION postgis') - # ActiveRecord::Base.connection.execute('CREATE EXTENSION postgis_topology') + enable_extension 'postgis' + # enable_extension 'postgis_topology' # This extension is NOT used. end end diff --git a/db/migrate/20140410190430_add_hstore_extension.rb b/db/migrate/20140410190430_add_hstore_extension.rb index eceec334ed..dbd718d8c2 100644 --- a/db/migrate/20140410190430_add_hstore_extension.rb +++ b/db/migrate/20140410190430_add_hstore_extension.rb @@ -1,9 +1,5 @@ class AddHstoreExtension < ActiveRecord::Migration[4.2] - def up - execute 'CREATE EXTENSION IF NOT EXISTS hstore' - end - - def down - execute 'DROP EXTENSION hstore' + def change + enable_extension 'hstore' end end diff --git a/db/migrate/20140701160736_add_extension_fuzzy_match_str.rb b/db/migrate/20140701160736_add_extension_fuzzy_match_str.rb index 9a078c7445..fb36942620 100644 --- a/db/migrate/20140701160736_add_extension_fuzzy_match_str.rb +++ b/db/migrate/20140701160736_add_extension_fuzzy_match_str.rb @@ -1,9 +1,5 @@ class AddExtensionFuzzyMatchStr < ActiveRecord::Migration[4.2] - def up - execute 'CREATE EXTENSION IF NOT EXISTS fuzzystrmatch' - end - - def down - execute 'DROP EXTENSION fuzzystrmatch' + def change + enable_extension 'fuzzystrmatch' end end diff --git a/db/migrate/20240212210249_create_active_storage_tables.active_storage.rb b/db/migrate/20240212210249_create_active_storage_tables.active_storage.rb new file mode 100644 index 0000000000..e4706aa21c --- /dev/null +++ b/db/migrate/20240212210249_create_active_storage_tables.active_storage.rb @@ -0,0 +1,57 @@ +# This migration comes from active_storage (originally 20170806125915) +class CreateActiveStorageTables < ActiveRecord::Migration[7.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :active_storage_blobs, id: primary_key_type do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name, null: false + t.bigint :byte_size, null: false + t.string :checksum + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :key ], unique: true + end + + create_table :active_storage_attachments, id: primary_key_type do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + t.references :blob, null: false, type: foreign_key_type + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + + create_table :active_storage_variant_records, id: primary_key_type do |t| + t.belongs_to :blob, null: false, index: false, type: foreign_key_type + t.string :variation_digest, null: false + + t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [primary_key_type, foreign_key_type] + end +end diff --git a/db/schema.rb b/db/schema.rb index 7f0c00cf31..4625552535 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,8 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_02_09_173244) do - +ActiveRecord::Schema[7.1].define(version: 2024_02_09_173244) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gin" enable_extension "fuzzystrmatch" @@ -26,8 +25,8 @@ t.text "value", null: false t.string "type", null: false t.integer "language_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.string "alternate_value_object_attribute" @@ -48,8 +47,8 @@ t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "is_absent" t.index ["created_by_id"], name: "index_asserted_distributions_on_created_by_id" t.index ["geographic_area_id"], name: "index_asserted_distributions_on_geographic_area_id" @@ -66,8 +65,8 @@ t.bigint "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["attribution_object_id"], name: "attr_obj_id_index" t.index ["attribution_object_type", "attribution_object_id"], name: "attribution_object_index" t.index ["attribution_object_type"], name: "attr_obj_type_index" @@ -78,17 +77,14 @@ create_table "biocuration_classifications", id: :serial, force: :cascade do |t| t.integer "biocuration_class_id", null: false - t.bigint "biological_collection_object_id" + t.integer "biological_collection_object_id", null: false t.integer "position", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.bigint "biocuration_classification_object_id" - t.string "biocuration_classification_object_type" t.index ["biocuration_class_id"], name: "index_biocuration_classifications_on_biocuration_class_id" - t.index ["biocuration_classification_object_type", "biocuration_classification_object_id"], name: "bc_poly" t.index ["biological_collection_object_id"], name: "bio_c_bio_collection_object" t.index ["created_by_id"], name: "index_biocuration_classifications_on_created_by_id" t.index ["position"], name: "index_biocuration_classifications_on_position" @@ -102,8 +98,8 @@ t.string "biological_association_subject_type", null: false t.integer "biological_association_object_id", null: false t.string "biological_association_object_type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -119,8 +115,8 @@ create_table "biological_associations_biological_associations_graphs", id: :serial, force: :cascade do |t| t.integer "biological_associations_graph_id", null: false t.integer "biological_association_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -132,8 +128,8 @@ end create_table "biological_associations_graphs", id: :serial, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -148,8 +144,8 @@ t.string "type", null: false t.integer "biological_property_id", null: false t.integer "biological_relationship_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -165,8 +161,8 @@ t.string "name", null: false t.boolean "is_transitive" t.boolean "is_reflexive" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -181,8 +177,8 @@ t.bigint "geographic_item_id" t.bigint "translated_geographic_item_id" t.string "cached_map_type" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["cached_map_type"], name: "cmgit_cmt" t.index ["geographic_item_id", "translated_geographic_item_id", "cached_map_type"], name: "cmgit_translation", unique: true t.index ["geographic_item_id"], name: "cmgit_gi" @@ -199,8 +195,8 @@ t.string "level1_geographic_name" t.string "level2_geographic_name" t.bigint "project_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "untranslated" t.index ["geographic_item_id"], name: "index_cached_map_items_on_geographic_item_id" t.index ["otu_id", "geographic_item_id"], name: "index_cached_map_items_on_otu_id_and_geographic_item_id" @@ -212,8 +208,8 @@ t.string "cached_map_register_object_type" t.bigint "cached_map_register_object_id" t.bigint "project_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["cached_map_register_object_type", "cached_map_register_object_id"], name: "index_cached_map_registers_on_cached_map_register_object" t.index ["project_id"], name: "index_cached_map_registers_on_project_id" end @@ -223,8 +219,8 @@ t.geography "geometry", limit: {:srid=>4326, :type=>"geometry", :geographic=>true} t.integer "reference_count" t.bigint "project_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "cached_map_type", null: false t.index ["otu_id"], name: "index_cached_maps_on_otu_id" t.index ["project_id"], name: "index_cached_maps_on_project_id" @@ -238,8 +234,8 @@ t.integer "project_id" t.integer "updated_by_id", null: false t.integer "created_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "description_name" t.string "key_name" t.index ["created_by_id"], name: "index_character_states_on_created_by_id" @@ -254,8 +250,8 @@ t.integer "topic_id", null: false t.integer "citation_id", null: false t.string "pages" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -269,8 +265,8 @@ create_table "citations", id: :serial, force: :cascade do |t| t.string "citation_object_type", null: false t.integer "source_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -303,8 +299,8 @@ t.string "elevation_precision" t.text "field_notes" t.string "md5_of_verbatim_label" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.text "cached" t.integer "created_by_id", null: false t.integer "updated_by_id", null: false @@ -348,8 +344,8 @@ t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_collection_object_observations_on_created_by_id" t.index ["data"], name: "index_collection_object_observations_on_data" t.index ["project_id"], name: "index_collection_object_observations_on_project_id" @@ -359,8 +355,8 @@ create_table "collection_objects", id: :serial, force: :cascade do |t| t.integer "total" t.string "type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "preparation_type_id" t.integer "repository_id" t.integer "created_by_id", null: false @@ -407,8 +403,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "collection_type" t.index ["collection_type"], name: "index_collection_profiles_on_collection_type" t.index ["container_id"], name: "index_collection_profiles_on_container_id" @@ -428,8 +424,8 @@ t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_common_names_on_created_by_id" t.index ["geographic_area_id"], name: "index_common_names_on_geographic_area_id" t.index ["language_id"], name: "index_common_names_on_language_id" @@ -446,8 +442,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "confidence_level_id", null: false t.index ["project_id"], name: "index_confidences_on_project_id" end @@ -461,8 +457,8 @@ end create_table "container_items", id: :serial, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "contained_object_id", null: false t.string "contained_object_type", null: false t.string "disposition" @@ -480,8 +476,8 @@ end create_table "containers", id: :serial, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "type", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false @@ -503,8 +499,8 @@ t.text "text", null: false t.integer "otu_id", null: false t.integer "topic_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -524,8 +520,8 @@ t.string "type", null: false t.string "name", null: false t.text "definition", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -551,8 +547,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["attribute_subject_id", "attribute_subject_type"], name: "index_data_attributes_on_attribute_subject_id_and_type" t.index ["attribute_subject_id"], name: "index_data_attributes_on_attribute_subject_id" t.index ["attribute_subject_type"], name: "index_data_attributes_on_attribute_subject_type" @@ -579,8 +575,8 @@ t.string "type", null: false t.string "status", null: false t.jsonb "metadata" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.bigint "project_id" @@ -597,13 +593,13 @@ t.integer "attempts", default: 0, null: false t.text "handler", null: false t.text "last_error" - t.datetime "run_at" - t.datetime "locked_at" - t.datetime "failed_at" + t.datetime "run_at", precision: nil + t.datetime "locked_at", precision: nil + t.datetime "failed_at", precision: nil t.string "locked_by" t.string "queue" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["priority", "run_at"], name: "delayed_jobs_priority" end @@ -614,8 +610,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "position" t.text "caption" t.string "figure_label" @@ -641,8 +637,8 @@ t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["collection_object_id"], name: "dco_collection_object" t.index ["collection_object_observation_id"], name: "dco_collection_object_observation" t.index ["project_id"], name: "index_derived_collection_objects_on_project_id" @@ -655,8 +651,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "position" t.text "description" t.string "gene_attribute_logic" @@ -679,8 +675,8 @@ t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "position" t.index ["created_by_id"], name: "index_documentation_on_created_by_id" t.index ["document_id"], name: "index_documentation_on_document_id" @@ -693,12 +689,12 @@ t.string "document_file_file_name", null: false t.string "document_file_content_type", null: false t.bigint "document_file_file_size", null: false - t.datetime "document_file_updated_at", null: false + t.datetime "document_file_updated_at", precision: nil, null: false t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.jsonb "page_map", default: {} t.integer "page_total" t.string "document_file_fingerprint" @@ -714,10 +710,10 @@ t.string "description" t.string "filename", null: false t.string "request" - t.datetime "expires", null: false + t.datetime "expires", precision: nil, null: false t.integer "times_downloaded", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.bigint "project_id" @@ -906,8 +902,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "identifiedByID" t.string "recordedByID" t.text "verbatimLabel" @@ -930,31 +926,13 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.bigint "repository_id" t.index ["project_id"], name: "index_extracts_on_project_id" t.index ["repository_id"], name: "index_extracts_on_repository_id" end - create_table "field_occurrences", force: :cascade do |t| - t.integer "total", null: false - t.bigint "collecting_event_id", null: false - t.bigint "ranged_lot_category_id" - t.boolean "is_absent" - t.integer "created_by_id", null: false - t.integer "updated_by_id", null: false - t.bigint "project_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["collecting_event_id"], name: "index_field_occurrences_on_collecting_event_id" - t.index ["created_by_id"], name: "index_field_occurrences_on_created_by_id" - t.index ["is_absent"], name: "index_field_occurrences_on_is_absent" - t.index ["project_id"], name: "index_field_occurrences_on_project_id" - t.index ["ranged_lot_category_id"], name: "index_field_occurrences_on_ranged_lot_category_id" - t.index ["updated_by_id"], name: "index_field_occurrences_on_updated_by_id" - end - create_table "gene_attributes", id: :serial, force: :cascade do |t| t.integer "descriptor_id", null: false t.integer "sequence_id", null: false @@ -964,8 +942,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["controlled_vocabulary_term_id"], name: "index_gene_attributes_on_controlled_vocabulary_term_id" t.index ["project_id"], name: "index_gene_attributes_on_project_id" t.index ["sequence_id"], name: "index_gene_attributes_on_sequence_id" @@ -981,8 +959,8 @@ create_table "geographic_area_types", id: :serial, force: :cascade do |t| t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.index ["created_by_id"], name: "index_geographic_area_types_on_created_by_id" @@ -997,8 +975,8 @@ t.integer "level2_id" t.integer "parent_id" t.integer "geographic_area_type_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "iso_3166_a2" t.string "iso_3166_a3" t.string "tdwgID" @@ -1022,16 +1000,16 @@ t.integer "origin_gid" t.string "date_valid_from" t.string "date_valid_to" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["data_origin"], name: "index_geographic_areas_geographic_items_on_data_origin" t.index ["geographic_area_id"], name: "index_geographic_areas_geographic_items_on_geographic_area_id" t.index ["geographic_item_id"], name: "index_geographic_areas_geographic_items_on_geographic_item_id" end create_table "geographic_items", id: :serial, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.geography "point", limit: {:srid=>4326, :type=>"st_point", :has_z=>true, :geographic=>true} t.geography "line_string", limit: {:srid=>4326, :type=>"line_string", :has_z=>true, :geographic=>true} t.geography "polygon", limit: {:srid=>4326, :type=>"st_polygon", :has_z=>true, :geographic=>true} @@ -1064,8 +1042,8 @@ t.integer "error_geographic_item_id" t.string "type", null: false t.integer "position", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "is_public", default: false, null: false t.string "api_request" t.integer "created_by_id", null: false @@ -1089,8 +1067,8 @@ create_table "identifiers", id: :serial, force: :cascade do |t| t.string "identifier", null: false t.string "type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "namespace_id" t.integer "created_by_id", null: false t.integer "updated_by_id", null: false @@ -1121,12 +1099,12 @@ t.string "image_file_fingerprint" t.integer "created_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "image_file_file_name" t.string "image_file_content_type" t.bigint "image_file_file_size" - t.datetime "image_file_updated_at" + t.datetime "image_file_updated_at", precision: nil t.integer "updated_by_id", null: false t.text "image_file_meta" t.float "pixels_to_centimeter" @@ -1141,15 +1119,15 @@ t.string "status", null: false t.string "description", null: false t.jsonb "metadata" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.bigint "project_id" t.string "source_file_name" t.string "source_content_type" t.bigint "source_file_size" - t.datetime "source_updated_at" + t.datetime "source_updated_at", precision: nil t.index ["created_by_id"], name: "index_import_datasets_on_created_by_id" t.index ["project_id"], name: "index_import_datasets_on_project_id" t.index ["updated_by_id"], name: "index_import_datasets_on_updated_by_id" @@ -1158,8 +1136,8 @@ create_table "imports", id: :serial, force: :cascade do |t| t.string "name" t.hstore "metadata" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.json "metadata_json" end @@ -1174,8 +1152,8 @@ t.integer "project_id" t.integer "created_by_id" t.integer "updated_by_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "type" t.index ["created_by_id"], name: "labels_created_by_id_index" t.index ["label_object_type", "label_object_id"], name: "index_labels_on_label_object_type_and_label_object_id" @@ -1189,48 +1167,14 @@ t.string "alpha_2" t.string "english_name" t.string "french_name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.index ["created_by_id"], name: "index_languages_on_created_by_id" t.index ["updated_by_id"], name: "index_languages_on_updated_by_id" end - create_table "lead_hierarchies", id: false, force: :cascade do |t| - t.integer "ancestor_id", null: false - t.integer "descendant_id", null: false - t.integer "generations", null: false - t.index ["ancestor_id", "descendant_id", "generations"], name: "lead_anc_desc_idx", unique: true - t.index ["descendant_id"], name: "lead_desc_idx" - end - - create_table "leads", force: :cascade do |t| - t.bigint "parent_id" - t.bigint "otu_id" - t.text "text" - t.string "origin_label" - t.text "description" - t.bigint "redirect_id" - t.text "link_out" - t.string "link_out_text" - t.integer "position" - t.boolean "is_public" - t.bigint "project_id", null: false - t.integer "created_by_id", null: false - t.integer "updated_by_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false - t.index ["created_by_id"], name: "index_leads_on_created_by_id" - t.index ["otu_id"], name: "index_leads_on_otu_id" - t.index ["parent_id"], name: "index_leads_on_parent_id" - t.index ["position"], name: "index_leads_on_position" - t.index ["project_id"], name: "index_leads_on_project_id" - t.index ["redirect_id"], name: "index_leads_on_redirect_id" - t.index ["text"], name: "index_leads_on_text" - t.index ["updated_by_id"], name: "index_leads_on_updated_by_id" - end - create_table "loan_items", id: :serial, force: :cascade do |t| t.integer "loan_id", null: false t.date "date_returned" @@ -1238,8 +1182,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "loan_item_object_type" t.integer "loan_item_object_id" t.integer "total" @@ -1266,8 +1210,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "recipient_honorific" t.string "recipient_country" t.text "lender_address", null: false @@ -1282,8 +1226,8 @@ t.string "institution" t.string "name", null: false t.string "short_name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.string "verbatim_short_name" @@ -1300,8 +1244,8 @@ t.integer "note_object_id", null: false t.string "note_object_type", null: false t.string "note_object_attribute" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -1316,8 +1260,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_observation_matrices_on_created_by_id" t.index ["name"], name: "index_observation_matrices_on_name" t.index ["project_id"], name: "index_observation_matrices_on_project_id" @@ -1332,8 +1276,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "position" t.index ["controlled_vocabulary_term_id"], name: "omrc_cvt_index" t.index ["created_by_id"], name: "index_observation_matrix_column_items_on_created_by_id" @@ -1350,8 +1294,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "reference_count" t.integer "cached_observation_matrix_column_item_id" t.index ["created_by_id"], name: "index_observation_matrix_columns_on_created_by_id" @@ -1368,8 +1312,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "position" t.bigint "taxon_name_id" t.integer "observation_object_id" @@ -1389,8 +1333,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "reference_count" t.integer "cached_observation_matrix_row_item_id" t.string "name" @@ -1425,8 +1369,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "type", null: false t.integer "observation_object_id" t.string "observation_object_type" @@ -1458,8 +1402,8 @@ t.integer "parent_organization_id" t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_organizations_on_created_by_id" t.index ["name"], name: "index_organizations_on_name" t.index ["updated_by_id"], name: "index_organizations_on_updated_by_id" @@ -1474,8 +1418,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_origin_relationships_on_created_by_id" t.index ["new_object_type", "new_object_id"], name: "index_origin_relationships_on_new_object_type_and_new_object_id" t.index ["old_object_type", "old_object_id"], name: "index_origin_relationships_on_old_object_type_and_old_object_id" @@ -1492,8 +1436,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_otu_page_layout_sections_on_created_by_id" t.index ["otu_page_layout_id"], name: "index_otu_page_layout_sections_on_otu_page_layout_id" t.index ["position"], name: "index_otu_page_layout_sections_on_position" @@ -1508,8 +1452,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_otu_page_layouts_on_created_by_id" t.index ["project_id"], name: "index_otu_page_layouts_on_project_id" t.index ["updated_by_id"], name: "index_otu_page_layouts_on_updated_by_id" @@ -1522,8 +1466,8 @@ t.bigint "project_id" t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["created_by_id"], name: "index_otu_relationships_on_created_by_id" t.index ["object_otu_id"], name: "index_otu_relationships_on_object_otu_id" t.index ["project_id"], name: "index_otu_relationships_on_project_id" @@ -1533,8 +1477,8 @@ create_table "otus", id: :serial, force: :cascade do |t| t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -1551,8 +1495,8 @@ t.string "type", null: false t.string "last_name", null: false t.string "first_name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "suffix" t.string "prefix" t.integer "created_by_id", null: false @@ -1581,8 +1525,8 @@ t.integer "inserted_count" t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_pinboard_items_on_created_by_id" t.index ["pinned_object_type", "pinned_object_id"], name: "index_pinboard_items_on_pinned_object_type_and_pinned_object_id" t.index ["position"], name: "index_pinboard_items_on_position" @@ -1593,8 +1537,8 @@ create_table "preparation_types", id: :serial, force: :cascade do |t| t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.text "definition", null: false @@ -1605,8 +1549,8 @@ create_table "project_members", id: :serial, force: :cascade do |t| t.integer "project_id", null: false t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.boolean "is_project_administrator" @@ -1622,8 +1566,8 @@ t.integer "source_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["created_by_id"], name: "index_project_sources_on_created_by_id" t.index ["project_id"], name: "index_project_sources_on_project_id" t.index ["source_id"], name: "index_project_sources_on_source_id" @@ -1632,8 +1576,8 @@ create_table "projects", id: :serial, force: :cascade do |t| t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.jsonb "preferences", default: "{}", null: false @@ -1651,8 +1595,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["project_id"], name: "index_protocol_relationships_on_project_id" t.index ["protocol_id"], name: "index_protocol_relationships_on_protocol_id" end @@ -1664,8 +1608,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["project_id"], name: "index_protocols_on_project_id" end @@ -1676,8 +1620,8 @@ t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "content_id", null: false t.index ["content_id"], name: "index_public_contents_on_content_id" t.index ["created_by_id"], name: "index_public_contents_on_created_by_id" @@ -1691,8 +1635,8 @@ t.string "name", null: false t.integer "minimum_value", null: false t.integer "maximum_value" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -1707,8 +1651,8 @@ t.string "acronym" t.string "status" t.string "institutional_LSID" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.boolean "is_index_herbariorum" @@ -1722,8 +1666,8 @@ t.integer "role_object_id", null: false t.string "role_object_type", null: false t.integer "position", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id" @@ -1745,8 +1689,8 @@ t.integer "object_sequence_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "project_id", null: false t.string "type", null: false end @@ -1754,8 +1698,8 @@ create_table "sequences", id: :serial, force: :cascade do |t| t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.text "sequence", null: false t.string "sequence_type", null: false t.integer "project_id", null: false @@ -1769,8 +1713,8 @@ t.integer "preceding_serial_id", null: false t.integer "succeeding_serial_id", null: false t.integer "created_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "updated_by_id", null: false t.string "type", null: false t.index ["created_by_id"], name: "index_serial_chronologies_on_created_by_id" @@ -1783,8 +1727,8 @@ create_table "serials", id: :serial, force: :cascade do |t| t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "place_published" t.integer "primary_language_id" t.integer "first_year_of_issue", limit: 2 @@ -1806,9 +1750,9 @@ t.string "unique_key", limit: 10, null: false t.string "category" t.integer "use_count", default: 0, null: false - t.datetime "expires_at" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "expires_at", precision: nil + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.index ["category"], name: "index_shortened_urls_on_category" t.index ["owner_id", "owner_type"], name: "index_shortened_urls_on_owner_id_and_owner_type" t.index ["unique_key"], name: "index_shortened_urls_on_unique_key", unique: true @@ -1825,8 +1769,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.bigint "project_id" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["created_by_id"], name: "index_sled_images_on_created_by_id" t.index ["image_id"], name: "index_sled_images_on_image_id" t.index ["project_id"], name: "index_sled_images_on_project_id" @@ -1863,8 +1807,8 @@ t.string "language" t.string "stated_year" t.string "verbatim" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "bibtex_type" t.integer "created_by_id", null: false t.integer "updated_by_id", null: false @@ -1910,11 +1854,11 @@ t.integer "project_id", null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.jsonb "result_boundary_coordinates" t.jsonb "result_ocr" - t.datetime "in_progress" + t.datetime "in_progress", precision: nil t.index ["depiction_id"], name: "index_sqed_depictions_on_depiction_id" t.index ["project_id"], name: "index_sqed_depictions_on_project_id" end @@ -1925,8 +1869,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "keyword_id", null: false t.index ["created_by_id"], name: "index_tagged_section_keywords_on_created_by_id" t.index ["keyword_id"], name: "index_tagged_section_keywords_on_keyword_id" @@ -1941,8 +1885,8 @@ t.integer "tag_object_id", null: false t.string "tag_object_type", null: false t.string "tag_object_attribute" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -1958,11 +1902,11 @@ end create_table "taxon_determinations", id: :serial, force: :cascade do |t| - t.bigint "biological_collection_object_id" + t.integer "biological_collection_object_id", null: false t.integer "otu_id", null: false t.integer "position", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -1970,22 +1914,19 @@ t.integer "month_made" t.integer "day_made" t.text "print_label" - t.bigint "taxon_determination_object_id" - t.string "taxon_determination_object_type" t.index ["biological_collection_object_id"], name: "index_taxon_determinations_on_biological_collection_object_id" t.index ["created_by_id"], name: "index_taxon_determinations_on_created_by_id" t.index ["otu_id"], name: "index_taxon_determinations_on_otu_id" t.index ["position"], name: "index_taxon_determinations_on_position" t.index ["project_id"], name: "index_taxon_determinations_on_project_id" - t.index ["taxon_determination_object_type", "taxon_determination_object_id"], name: "td_poly" t.index ["updated_by_id"], name: "index_taxon_determinations_on_updated_by_id" end create_table "taxon_name_classifications", id: :serial, force: :cascade do |t| t.integer "taxon_name_id", null: false t.string "type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -2010,8 +1951,8 @@ t.integer "subject_taxon_name_id", null: false t.integer "object_taxon_name_id", null: false t.string "type", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false @@ -2028,8 +1969,8 @@ t.integer "parent_id" t.string "cached_html" t.string "cached_author_year" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "year_of_publication" t.string "verbatim_author" t.string "rank_class" @@ -2081,8 +2022,8 @@ t.boolean "boolean" t.text "text" t.integer "integer" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", precision: nil + t.datetime "updated_at", precision: nil t.string "type" t.integer "sti_id" t.string "sti_type" @@ -2098,8 +2039,8 @@ t.integer "created_by_id", null: false t.integer "updated_by_id", null: false t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["collection_object_id"], name: "index_type_materials_on_collection_object_id" t.index ["created_by_id"], name: "index_type_materials_on_created_by_id" t.index ["project_id"], name: "index_type_materials_on_project_id" @@ -2111,17 +2052,17 @@ create_table "users", id: :serial, force: :cascade do |t| t.string "email", null: false t.string "password_digest", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "remember_token" t.integer "created_by_id" t.integer "updated_by_id" t.boolean "is_administrator" t.string "password_reset_token" - t.datetime "password_reset_token_date" + t.datetime "password_reset_token_date", precision: nil t.string "name", null: false - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" + t.datetime "current_sign_in_at", precision: nil + t.datetime "last_sign_in_at", precision: nil t.string "current_sign_in_ip" t.string "last_sign_in_ip" t.text "hub_tab_order", default: [], array: true @@ -2130,7 +2071,7 @@ t.json "footprints", default: {} t.integer "sign_in_count", default: 0 t.json "hub_favorites" - t.datetime "last_seen_at" + t.datetime "last_seen_at", precision: nil t.integer "time_active", default: 0 t.json "preferences", default: {} t.bigint "person_id" @@ -2154,7 +2095,7 @@ t.string "event", null: false t.string "whodunnit" t.text "object" - t.datetime "created_at", null: false + t.datetime "created_at", precision: nil, null: false t.integer "transaction_id" t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" t.index ["transaction_id"], name: "index_versions_on_transaction_id" @@ -2283,11 +2224,6 @@ add_foreign_key "extracts", "repositories" add_foreign_key "extracts", "users", column: "created_by_id" add_foreign_key "extracts", "users", column: "updated_by_id" - add_foreign_key "field_occurrences", "collecting_events" - add_foreign_key "field_occurrences", "projects" - add_foreign_key "field_occurrences", "ranged_lot_categories" - add_foreign_key "field_occurrences", "users", column: "created_by_id" - add_foreign_key "field_occurrences", "users", column: "updated_by_id" add_foreign_key "gene_attributes", "controlled_vocabulary_terms" add_foreign_key "gene_attributes", "projects" add_foreign_key "gene_attributes", "sequences" @@ -2325,10 +2261,6 @@ add_foreign_key "labels", "users", column: "updated_by_id", name: "labels_updated_by_id_fk" add_foreign_key "languages", "users", column: "created_by_id", name: "languages_created_by_id_fkey" add_foreign_key "languages", "users", column: "updated_by_id", name: "languages_updated_by_id_fkey" - add_foreign_key "leads", "leads", column: "parent_id" - add_foreign_key "leads", "leads", column: "redirect_id" - add_foreign_key "leads", "otus" - add_foreign_key "leads", "projects" add_foreign_key "loan_items", "loans", name: "loan_items_loan_id_fkey" add_foreign_key "loan_items", "projects", name: "loan_items_project_id_fkey" add_foreign_key "loan_items", "users", column: "created_by_id", name: "loan_items_created_by_id_fkey" diff --git a/k8s/dev/tw-secrets.yml b/k8s/dev/tw-secrets.yml index 859ce1bad2..665d4ba283 100644 --- a/k8s/dev/tw-secrets.yml +++ b/k8s/dev/tw-secrets.yml @@ -9,5 +9,5 @@ data: # echo -n foo | base64 db.root.password: dGF4b253b3Jrcw== # taxonworks db.user: dGF4b253b3Jrc19wcm9kdWN0aW9u # taxonworks_production db.user.password: dGF4b253b3Jrcw== # taxonworks - secret_key_base: cGFzc3dvcmQ= # password (replace with `rake secret`) + secret_key_base: cGFzc3dvcmQ= # password (replace with `rails secret`) nginx.secret: bmdpbnhfc2VjcmV0 # nginx_secret diff --git a/lib/batch_load/import.rb b/lib/batch_load/import.rb index 80d757b8e1..a5df8da6bb 100644 --- a/lib/batch_load/import.rb +++ b/lib/batch_load/import.rb @@ -179,17 +179,22 @@ def line_strict_level_ok? def create @create_attempted = true - if ready_to_create? # TODO: DRY if a = save_order - sorted_processed_rows.each_value do |rp| - a.each do |k| - rp.objects[k].each do |o| - o.save unless o.persisted? + a.each do |k| + sorted_processed_rows.each_value do |rp| + rp.objects[k].each do |o| + begin + # puts o.name + o.save! unless o.persisted? + rescue ActiveRecord::RecordInvalid => o + a = o.record + o.record + end + end end - end end else diff --git a/lib/batch_load/import/taxon_names/nomen_interpreter.rb b/lib/batch_load/import/taxon_names/nomen_interpreter.rb index 8ed4582245..22648eef69 100644 --- a/lib/batch_load/import/taxon_names/nomen_interpreter.rb +++ b/lib/batch_load/import/taxon_names/nomen_interpreter.rb @@ -17,7 +17,7 @@ class Import::TaxonNames::NomenInterpreter < BatchLoad::Import # Required to handle some defaults attr_accessor :project_id - SAVE_ORDER = [:original_taxon_name, :taxon_name, :taxon_name_relationship, :otu] + SAVE_ORDER = [:taxon_name, :taxon_name_relationship, :otu] # :original_taxon_name, # @param [Hash] args def initialize(nomenclature_code: nil, parent_taxon_name_id: nil, also_create_otu: false, **args) @@ -32,6 +32,10 @@ def parent_taxon_name_id @parent_taxon_name_id || root_taxon_name.id end + def parent_taxon_name + TaxonName.find(parent_taxon_name_id) + end + def also_create_otu return true if [1, '1', true].include?(@also_create_otu) false @@ -57,7 +61,7 @@ def build_taxon_names parse_result = BatchLoad::RowParse.new parse_result.row_number = i # check vs. header etc. - parse_result.objects[:original_taxon_name] = [] + # parse_result.objects[:original_taxon_name] = [] # not used parse_result.objects[:taxon_name] = [] parse_result.objects[:taxon_name_relationship] = [] parse_result.objects[:otu] = [] @@ -122,7 +126,7 @@ def build_taxon_names taxon_names[taxon_name_id] = p if parent_id.blank? - p.parent_id = parent_taxon_name_id + p.parent = parent_taxon_name else if taxon_names[parent_id] p.parent = taxon_names[parent_id] diff --git a/lib/housekeeping/users.rb b/lib/housekeeping/users.rb index b986f921d5..e619eaf7db 100644 --- a/lib/housekeeping/users.rb +++ b/lib/housekeeping/users.rb @@ -9,13 +9,9 @@ module Housekeeping::Users belongs_to :creator, foreign_key: :created_by_id, class_name: 'User', inverse_of: "created_#{related_instances}".to_sym belongs_to :updater, foreign_key: :updated_by_id, class_name: 'User', inverse_of: "updated_#{related_instances}".to_sym -# scope :created_by_user, ->(user) { where(created_by_id: User.get_user_id(user) ) } -# scope :updated_by_user, ->(user) { where(updated_by_id: User.get_user_id(user) ) } - - scope :created_or_updated_by, -> (user_id) { where(created_by_id: user_id).or(where(updated_by_id: user_id)) } - unless_user = lambda { self.class.name == 'User' && self.self_created } - validates :creator, presence: true, unless: unless_user # lambda, proc, or block + + validates :creator, presence: true, unless: unless_user validates :updater, presence: true, unless: unless_user before_validation(on: :create, unless: unless_user) do @@ -27,6 +23,8 @@ module Housekeeping::Users set_updated_by_id end + scope :created_or_updated_by, -> (user_id) { where(created_by_id: user_id).or(where(updated_by_id: user_id)) } + # And extend User User.class_eval do raise 'Class name collision for User#has_many' if self.methods and self.methods.include?(:related_instances) diff --git a/lib/queries/sqed_depiction/filter.rb b/lib/queries/sqed_depiction/filter.rb index d6633785ea..2326ee477a 100644 --- a/lib/queries/sqed_depiction/filter.rb +++ b/lib/queries/sqed_depiction/filter.rb @@ -49,10 +49,9 @@ def sqed_depiction_id [@sqed_depiction_id].flatten.compact end - # TODO: use WITH def base_collection_object_query_facet q = ::Queries::CollectionObject::Filter.new(base_collection_object_filter_params).all - ::SqedDepiction.joins(:collection_object).where(collection_objects: q) + ::SqedDepiction.joins(:collection_object).with(collection_objects: q) end def merge_clauses diff --git a/spec/controllers/pinboard_items_controller_spec.rb b/spec/controllers/pinboard_items_controller_spec.rb index 31d8e06005..0990a96513 100644 --- a/spec/controllers/pinboard_items_controller_spec.rb +++ b/spec/controllers/pinboard_items_controller_spec.rb @@ -32,7 +32,7 @@ } let(:invalid_attributes) { - {pinned_object_type: 'Smurf'} + {pinned_object_type_id: nil} } # This should return the minimal set of values that should be in the session diff --git a/spec/files/batch/taxon_name/NomenTest.tab b/spec/files/batch/taxon_name/NomenTest.tab index 43cd76047d..4b85c1f440 100644 --- a/spec/files/batch/taxon_name/NomenTest.tab +++ b/spec/files/batch/taxon_name/NomenTest.tab @@ -6,6 +6,6 @@ id taxon_name parent_id rank related_name_id related_name_nomen_class name_nomen 5 eus123 3 species TaxonNameClassification::Iczn::Unavailable::NotLatin 6 fus 4 species 7 gus 3 species 5 TaxonNameRelationship::Iczn::Invalidating::Synonym (Smith, 1920) https://my.uri/123 Cus nr. gus 22x -8 hus 4 species 6 TaxonNameRelationship::Iczn::Invalidating::Synonym (Jones) -9 ius 3 species 5 TaxonNameRelationship::Iczn::Invalidating::Synonym -10 jus 3 species 6 TaxonNameRelationship::Iczn::Invalidating::Synonym my_otu_name_22 +8 hus 4 species 6 TaxonNameRelationship::Iczn::Invalidating::Synonym::Suppression (Jones) +9 ius 3 species 5 TaxonNameRelationship::Iczn::Invalidating::Synonym::Subjective +10 jus 4 species 6 TaxonNameRelationship::Iczn::Invalidating::Synonym::Objective my_otu_name_22 diff --git a/spec/files/import_datasets/checklists/nomen_nudum.tsv b/spec/files/import_datasets/checklists/nomen_nudum.tsv index d5e70807dc..2258596d5d 100644 --- a/spec/files/import_datasets/checklists/nomen_nudum.tsv +++ b/spec/files/import_datasets/checklists/nomen_nudum.tsv @@ -1,4 +1,4 @@ -taxonID parentNameUsageID parentNameUsage acceptedNameUsageID acceptedNameUsage scientificName kingdom lass order family genus subgenus specificEpithet infraspecificEpithet taxonRank scientificNameAuthorship taxonomicStatus originalNameUsage originalNameUsageID namePublishedInYear nomenclaturalCode TW:TaxonNameClassification:Latinized:Gender TW:TaxonNameClassification:Latinized:PartOfSpeech +taxonID parentNameUsageID parentNameUsage acceptedNameUsageID acceptedNameUsage scientificName kingdom class order family genus subgenus specificEpithet infraspecificEpithet taxonRank scientificNameAuthorship taxonomicStatus originalNameUsage originalNameUsageID namePublishedInYear nomenclaturalCode TW:TaxonNameClassification:Latinized:Gender TW:TaxonNameClassification:Latinized:PartOfSpeech 429776 429776 Myrmica Latreille, 1804 Myrmica Animalia Insecta Hymenoptera Formicidae Genus Latreille, 1804 valid 429776 1804 ICZN 429929 429929 Leptothorax Mayr, 1855 Leptothorax Animalia Insecta Hymenoptera Formicidae Genus Mayr, 1855 valid 429929 1855 ICZN 429956 429956 Temnothorax Mayr, 1861 Temnothorax Animalia Insecta Hymenoptera Formicidae Genus Mayr, 1861 valid 429956 1861 ICZN diff --git a/spec/lib/batch_load/import/da_for_otus_spec.rb b/spec/lib/batch_load/import/da_for_otus_spec.rb index bab0aa538d..ad82c70904 100644 --- a/spec/lib/batch_load/import/da_for_otus_spec.rb +++ b/spec/lib/batch_load/import/da_for_otus_spec.rb @@ -20,7 +20,7 @@ } let(:source) { FactoryBot.create(:valid_source_verbatim) } - + let(:upload_file_2) { Rack::Test::UploadedFile.new(file_ph_2) } let(:import_2_im) { BatchLoad::Import::Otus::DataAttributesInterpreter.new( @@ -56,7 +56,7 @@ file: upload_file_2, type_select: 'import' ) } - + let(:import_no_new_otus) { BatchLoad::Import::Otus::DataAttributesInterpreter.new( project_id:, user_id: user.id, @@ -358,10 +358,7 @@ end specify '#valid_objects' do - # The 5 data attributes are shown as invalid because - # their base object is not yet saved. - # See polymorphic_annotator.rb validate associated - expect(import_2_in.valid_objects.count).to eq(14) + expect(import_2_in.valid_objects.count).to eq(19) end specify '#successful_rows' do diff --git a/spec/lib/batch_load/import/taxon_names/nomen_interpreter_spec.rb b/spec/lib/batch_load/import/taxon_names/nomen_interpreter_spec.rb index ad6616e5d0..2e63d151bd 100644 --- a/spec/lib/batch_load/import/taxon_names/nomen_interpreter_spec.rb +++ b/spec/lib/batch_load/import/taxon_names/nomen_interpreter_spec.rb @@ -27,21 +27,23 @@ let(:import) { BatchLoad::Import::TaxonNames::NomenInterpreter.new( **import_params ) } - #specify 'handle parent recursion errors gracefully' do - # f = Rack::Test::UploadedFile.new('spec/files/batch/taxon_name/NomenTestRecursive.tab') - # p = import_params - # p[:file] = f - # - # i = BatchLoad::Import::TaxonNames::NomenInterpreter.new( **p ) + #specify 'handle parent recursion errors gracefully' do + # f = Rack::Test::UploadedFile.new('spec/files/batch/taxon_name/NomenTestRecursive.tab') + # p = import_params + # p[:file] = f + # + # i = BatchLoad::Import::TaxonNames::NomenInterpreter.new( **p ) - # i.build - # expect(i.create).to be_truthy - #end + # i.build + # expect(i.create).to be_truthy + #end specify 'parent_taxon_name_id (provided)' do g = Protonym.create!(parent: root_taxon_name, name: 'Orderum', rank_class: Ranks.lookup(:iczn, :order)) + i = BatchLoad::Import::TaxonNames::NomenInterpreter.new( **import_params.merge(parent_taxon_name_id: g.id) ) i.create + expect(TaxonName.find_by(name: 'Aidae').parent_id).to eq(g.id) expect(TaxonName.find_by(name: 'Bidae').parent_id).to eq(g.id) end diff --git a/spec/models/citation_spec.rb b/spec/models/citation_spec.rb index 78110362eb..11e260f7d8 100644 --- a/spec/models/citation_spec.rb +++ b/spec/models/citation_spec.rb @@ -7,11 +7,10 @@ let(:topic) { FactoryBot.create(:valid_topic) } let(:pdf) { Rack::Test::UploadedFile.new( Spec::Support::Utilities::Files.generate_pdf(pages: 10) ) } - specify '.batch_create 1' do o1 = FactoryBot.create(:valid_otu) o2 = FactoryBot.create(:valid_otu) - + s = FactoryBot.create(:valid_source) h = { @@ -23,9 +22,9 @@ p = ActionController::Parameters.new(h) p.permit! - + Citation.batch_create(p) - + expect(Citation.count).to eq(2) expect(Citation.first.pages).to eq('22') end @@ -156,16 +155,18 @@ let(:c3) { Citation.new() } specify 'one is_original per citation_object' do - c1.update(is_original: true) + c1.update!(is_original: true) c2.is_original = true expect(c2.valid?).to be_falsey expect(c2.errors[:is_original]).to be_truthy end - specify 'many is_original is false per citation_object' do - c1.update(is_original: false) - c2.is_original = false + specify 'many is_original is invalid per citation_object' do + c1.update!(is_original: false) expect(c1.valid?).to be_truthy + + # !! validates_uniqueness of now crosses into in-memory objects + c2.is_original = false expect(c2.errors[:is_original].empty?).to be_truthy end @@ -206,7 +207,7 @@ c3.citation_object = otu expect(c3.valid?).to be_falsey - expect(c3.errors.messages[:source]).to be_truthy + expect(c3.errors.messages[:source]).to be_truthy end end diff --git a/spec/models/concerns/shared/loanable_spec.rb b/spec/models/concerns/shared/loanable_spec.rb index 55d7bbf812..669215e002 100644 --- a/spec/models/concerns/shared/loanable_spec.rb +++ b/spec/models/concerns/shared/loanable_spec.rb @@ -98,10 +98,13 @@ specify 'setting loan_item sets loan' do class_with_loan.save! - class_with_loan.build_loan_item(loan:) - class_with_loan.save! - expect(class_with_loan.loan_item.id).to be_truthy + class_with_loan.create_loan_item(loan:) + + # No longer saves the build + # class_with_loan.save! + + expect(class_with_loan.reload_loan_item.id).to be_truthy end specify 'has_one loan' do diff --git a/spec/models/protonym/authorship_spec.rb b/spec/models/protonym/authorship_spec.rb index a72c7816d2..ebe4cd618a 100644 --- a/spec/models/protonym/authorship_spec.rb +++ b/spec/models/protonym/authorship_spec.rb @@ -19,9 +19,9 @@ context 'by nested attributes' do let(:name) { Protonym.create!( - name: 'aus', - parent: root, - rank_class: Ranks.lookup(:iczn, :species), + name: 'aus', + parent: root, + rank_class: Ranks.lookup(:iczn, :species), taxon_name_author_roles_attributes: [ {person_id: p1.id}, {person: p2}, @@ -35,22 +35,22 @@ context 'updating roles' do let(:name) { Protonym.create!( - name: 'aus', - parent: root, - rank_class: Ranks.lookup(:iczn, :species), + name: 'aus', + parent: root, + rank_class: Ranks.lookup(:iczn, :species), taxon_name_author_roles_attributes: [ {person_id: p1.id}])} let(:first_role_id) {name.taxon_name_author_roles.first.id } - + specify '#author_string 1' do name.update(taxon_name_author_roles_attributes: [{_destroy: true, id: first_role_id}, {person: p2}]) expect(name.author_string).to eq('Jones') end - specify '#author_string 2' do - name.update(roles_attributes: [{_destroy: true, id: first_role_id}, {type: 'TaxonNameAuthor', person: p2}]) - expect(name.author_string).to eq('Jones') - end + specify '#author_string 2' do + name.update(roles_attributes: [{_destroy: true, id: first_role_id}, {type: 'TaxonNameAuthor', person: p2}]) + expect(name.author_string).to eq('Jones') + end end end diff --git a/spec/models/protonym/original_combinations_spec.rb b/spec/models/protonym/original_combinations_spec.rb index bf3e8c595e..95fd7cf743 100644 --- a/spec/models/protonym/original_combinations_spec.rb +++ b/spec/models/protonym/original_combinations_spec.rb @@ -63,7 +63,7 @@ end context 'cached fields with verbatim_name set' do - before { species.update(verbatim_name: 'albo-nigra', original_genus: alternate_genus) } + before { species.update!(verbatim_name: 'albo-nigra', original_genus: alternate_genus) } specify '#cached_original_combination' do expect(species.cached_original_combination).to eq('Bus albo-nigra') @@ -105,68 +105,69 @@ end specify '#original_genus set' do - species.update(original_genus: genus) + species.update!(original_genus: genus) expect(species.cached_original_combination).to eq('Aus aus') end specify '#original_genus, #original_subgenus set' do - species.update(original_genus: genus, original_subgenus: genus) + species.update!(original_genus: genus, original_subgenus: genus) expect(species.cached_original_combination).to eq('Aus (Aus) aus') end specify '#original_genus, #original_subgenus, #original_species set' do - species.update(original_genus: genus, original_subgenus: genus, original_species: species) + species.update!(original_genus: genus, original_subgenus: genus, original_species: species) expect(species.cached_original_combination).to eq('Aus (Aus) aus') end specify '#original_genus, #original_subgenus, #original_species, #original_subspecies set' do - species.update(original_genus: genus, original_subgenus: genus, original_species: species, original_subspecies: species) + species.update!(original_genus: genus, original_subgenus: genus, original_species: species, original_subspecies: species) expect(species.cached_original_combination).to eq('Aus (Aus) aus aus') end specify '#original_genus, #original_subgenus, #original_species, #original_subspecies, #original_variety set' do - species.update(original_genus: genus, original_subgenus: genus, original_species: species, original_subspecies: species, original_variety: species) + species.update!(original_genus: genus, original_subgenus: genus, original_species: species, original_subspecies: species, original_variety: species) expect(species.cached_original_combination).to eq('Aus (Aus) aus aus var. aus') end specify '#original_genus, #original_subgenus, #original_species, #original_subspecies, #original_variety set' do - species.update(original_genus: genus, original_subgenus: genus, original_species: species, original_subspecies: species, original_variety: species) + species.update!(original_genus: genus, original_subgenus: genus, original_species: species, original_subspecies: species, original_variety: species) expect(species.cached_original_combination_html).to eq('Aus (Aus) aus aus var. aus') end specify 'subgenus original combination' do - alternate_genus.update(parent: genus, rank_class: Ranks.lookup(:iczn, :subgenus), original_genus: alternate_genus) + alternate_genus.update!(parent: genus, rank_class: Ranks.lookup(:iczn, :subgenus), original_genus: alternate_genus) expect(alternate_genus.cached_original_combination).to eq('Bus') end specify 'incomplete relationship: missing original species' do - species.update(original_genus: genus, original_subspecies: species) + species.update!(original_genus: genus, original_subspecies: species) expect(species.cached_original_combination).to eq('Aus [SPECIES NOT SPECIFIED] aus') end specify 'incomplete relationship: missing original genus 1' do - species.update(original_genus: nil, original_subgenus: genus) + species.update!(original_genus: nil, original_subgenus: genus) expect(species.cached_original_combination).to eq('[GENUS NOT SPECIFIED] (Aus) aus') end specify 'incomplete relationship: missing original genus 2' do - species.update(original_genus: nil, original_subgenus: genus) + species.update!(original_genus: nil, original_subgenus: genus) expect(species.cached_original_combination_html).to eq('[GENUS NOT SPECIFIED] (Aus) aus') end + # Creating a TNR does not reload the related object anymore specify 'misspelled original combination 1' do - alternate_genus.update(iczn_set_as_misspelling_of: genus, original_genus: alternate_genus) - expect(alternate_genus.cached_original_combination).to eq('Bus [sic]') + alternate_genus.update!(iczn_set_as_misspelling_of: genus, original_genus: alternate_genus) + expect(alternate_genus.reload.cached_original_combination).to eq('Bus [sic]') end specify 'misspelled original combination 2' do - alternate_genus.update(iczn_set_as_misspelling_of: genus, original_genus: alternate_genus) - expect(alternate_genus.cached_original_combination_html).to eq('Bus [sic]') + alternate_genus.update!(iczn_set_as_misspelling_of: genus, original_genus: alternate_genus) + expect(alternate_genus.reload.cached_original_combination_html).to eq('Bus [sic]') end specify 'misspelled original combination 3' do - alternate_genus.update(iczn_set_as_misspelling_of: genus, original_genus: alternate_genus) - species.update(original_genus: alternate_genus) + alternate_genus.update!(iczn_set_as_misspelling_of: genus, original_genus: alternate_genus) + species.update!(original_genus: alternate_genus) # touching this updates cached, so this differs from above 2 specs expect(species.cached_original_combination_html).to eq('Bus [sic] aus') end diff --git a/spec/models/taxon_name/cached_spec.rb b/spec/models/taxon_name/cached_spec.rb index ae4ac0b6cf..7191a26047 100644 --- a/spec/models/taxon_name/cached_spec.rb +++ b/spec/models/taxon_name/cached_spec.rb @@ -4,14 +4,15 @@ let(:root) { FactoryBot.create(:root_taxon_name) } - after(:all) do - TaxonNameRelationship.delete_all - TaxonName.delete_all - TaxonNameHierarchy.delete_all - # TODO: find out why this exists and resolve - presently leaving sources in the models - Citation.delete_all - Source.destroy_all - end + + # after(:all) do + # TaxonNameRelationship.delete_all + # TaxonName.delete_all + # TaxonNameHierarchy.delete_all + # # TODO: find out why this exists and resolve - presently leaving sources in the models + # Citation.delete_all + # Source.destroy_all + # end context 'quick test' do let(:genus) { Protonym.create(name: 'Erasmoneura', rank_class: Ranks.lookup(:iczn, 'genus'), parent: root) } @@ -26,10 +27,7 @@ specify '#not_specified 1' do species.update!(parent: root, original_genus: nil) - - # !! At this point species.cached == "[GENUS NOT SPECIFIED] vulnerata". See #2236 - - expect(species.reload.cached).to eq('[GENUS NOT SPECIFIED] vulnerata') + expect(species.cached).to eq('[GENUS NOT SPECIFIED] vulnerata') end end @@ -252,7 +250,7 @@ expect(species.not_binominal?).to be_falsey species.taxon_name_classifications.create(type: 'TaxonNameClassification::Iczn::Unavailable::NonBinominal') expect(species.not_binominal?).to be_truthy - species.reload +# species.reload species.save expect(species.cached_html).to eq('Cus aus') end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 1e10598da8..d0bb5d7007 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -11,7 +11,7 @@ require_relative '../config/environment' -ActiveRecord::Migration.check_pending! +ActiveRecord::Migration.check_all_pending! ActiveRecord::Migration.maintain_test_schema! require 'amazing_print' @@ -29,4 +29,3 @@ ApplicationRecord.connection.tables.each { |t| ApplicationRecord.connection.reset_pk_sequence!(t) } FactoryBot.use_parent_strategy = false - diff --git a/spec/support/controller_spec_helper.rb b/spec/support/controller_spec_helper.rb index f129450042..6d5e2c68bd 100644 --- a/spec/support/controller_spec_helper.rb +++ b/spec/support/controller_spec_helper.rb @@ -1,27 +1,27 @@ # Helpers for controller specs (typically those automatically generated). -# +# # These methods should be used within a before(:each) block. module ControllerSpecHelper def sign_in_user_and_select_project(user, project_id) - @request.session = {project_id: project_id} + @request.session = ActionController::TestSession.new(project_id: 1) remember_token = User.secure_random_token cookies.permanent[:remember_token] = remember_token - user.update_attribute(:remember_token, User.encrypt(remember_token)) + user.update_attribute(:remember_token, User.encrypt(remember_token)) set_user_project(user.id,project_id) end # Signs in user 1 and project 1. def sign_in - @request.session = {project_id: 1} + @request.session = ActionController::TestSession.new(project_id: 1) remember_token = User.secure_random_token cookies.permanent[:remember_token] = remember_token - User.find(1).update_attribute(:remember_token, User.encrypt(remember_token)) + User.find(1).update_attribute(:remember_token, User.encrypt(remember_token)) set_user_project(1,1) end def sign_in_administrator - @request.session = {project_id: 1} + @request.session = ActionController::TestSession.new(project_id: 1) remember_token = User.secure_random_token cookies.permanent[:remember_token] = remember_token @@ -33,23 +33,23 @@ def sign_in_administrator end def sign_in_project_administrator - @request.session = {project_id: 1} + @request.session = ActionController::TestSession.new(project_id: 1) remember_token = User.secure_random_token cookies.permanent[:remember_token] = remember_token pwd = 'abcD123!' user = User.create!(name: 'Administrator (controller tests)', email: 'foo@bar.com', password: pwd, password_confirmation: pwd, self_created: true) - user.update_attribute(:remember_token, User.encrypt(remember_token)) + user.update_attribute(:remember_token, User.encrypt(remember_token)) administrator = User.create!(name: 'Pat the Administrator', email: 'administrator@example.com', password: pwd, password_confirmation: pwd, is_administrator: true, self_created: true) - Project.find(1).project_members.create!(creator: administrator, updater: administrator, user: user, is_project_administrator: true) + Project.find(1).project_members.create!(creator: administrator, updater: administrator, user:, is_project_administrator: true) set_user_project(user.id, 1) end - # We do this to handle the pre-request stubbing of objects in controllers. - # It mocks the behaviour of having accessed at least one page post login. + # We do this to handle the pre-request stubbing of objects in controllers. + # It mocks the behaviour of having accessed at least one page post login. def set_user_project(user_id, project_id) Current.user_id = user_id Current.project_id = project_id @@ -64,5 +64,3 @@ def sign_in_user end end - -