From 73966e253ec832646b0171c91754adb462b394ab Mon Sep 17 00:00:00 2001 From: vangberg Date: Wed, 19 Aug 2026 13:40:38 +0200 Subject: [PATCH 1/3] Remove legacy `Name#incertae_sedis` --- app/controllers/placements_controller.rb | 8 +---- app/models/name.rb | 31 +++---------------- app/models/tutorial/batch.rb | 21 +++++++++---- app/views/names/_taxonomy.html.erb | 2 +- app/views/registers/table.html.erb | 2 +- ...100000_remove_incertae_sedis_from_names.rb | 18 +++++++++++ db/schema.rb | 3 +- test/fixtures/names.yml | 20 ++++++++++++ test/fixtures/placements.yml | 5 +++ test/models/name_test.rb | 8 +++++ 10 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 db/migrate/20260819100000_remove_incertae_sedis_from_names.rb diff --git a/app/controllers/placements_controller.rb b/app/controllers/placements_controller.rb index dea89dfa..5977e723 100644 --- a/app/controllers/placements_controller.rb +++ b/app/controllers/placements_controller.rb @@ -15,16 +15,12 @@ def new Placement.new( name: @name, preferred: true, parent: @name.parent, publication: @name.assigned_in, - incertae_sedis: @name.incertae_sedis, - incertae_sedis_text: @name.incertae_sedis_text ).save! end unless @name.placement @placement.parent = @name.parent @placement.publication = @name.assigned_in - @placement.incertae_sedis = @name.incertae_sedis - @placement.incertae_sedis_text = @name.incertae_sedis_text @placement.preferred = true end end @@ -108,7 +104,6 @@ def create_or_update(back_action) end @name.update!( parent: @placement.parent, assigned_in: @placement.publication, - incertae_sedis: nil, incertae_sedis_text: nil ) end rescue @@ -130,8 +125,7 @@ def prefer @name.placement.try(:update!, preferred: false) @placement.update!(preferred: true) @name.update!( - parent: @placement.parent, assigned_in: @placement.publication, - incertae_sedis: nil, incertae_sedis_text: nil + parent: @placement.parent, assigned_in: @placement.publication ) ok = true end diff --git a/app/models/name.rb b/app/models/name.rb index 532ffa52..ce71f12d 100644 --- a/app/models/name.rb +++ b/app/models/name.rb @@ -28,6 +28,10 @@ class Name < ApplicationRecord :placements, -> { includes(:parent) }, dependent: :destroy, inverse_of: :name ) + delegate( + :incertae_sedis, :incertae_sedis?, :incertae_sedis_html, + :incertae_sedis_text, to: :placement, allow_nil: true + ) has_many( :child_placements, -> { includes(:name) }, class_name: 'Placement', foreign_key: 'parent_id', dependent: :destroy @@ -115,7 +119,6 @@ class Name < ApplicationRecord has_rich_text(:description) has_rich_text(:notes) has_rich_text(:etymology_text) - has_rich_text(:incertae_sedis_text) # deprecated, but values still in DB validates(:name, presence: true, uniqueness: true) validates( @@ -1001,12 +1004,6 @@ def type_name_alt_placement place if place != self end - def incertae_sedis_html - return '' unless incertae_sedis? - - incertae_sedis.gsub(/(incertae sedis)/i, '\\1').html_safe - end - def inferred_rank @inferred_rank ||= if rank? @@ -1175,18 +1172,6 @@ def propose_lineage_name(rank) end end - def incertae_sedis_explain - (placement || self).incertae_sedis_text - end - - def incertae_sedis - placement ? placement.incertae_sedis : self[:incertae_sedis] - end - - def incertae_sedis? - incertae_sedis.present? - end - def taxonomic_data? description? || notes? || parent || incertae_sedis? || taxonomic_status? || !children.empty? || !alt_child_placements.empty? @@ -1481,12 +1466,7 @@ def harmonize_register_and_status end def ensure_consistent_placement - placement_incertae_sedis = - if saved_change_to_incertae_sedis? - self[:incertae_sedis] - else - incertae_sedis - end + placement_incertae_sedis = incertae_sedis if parent_id.present? || placement_incertae_sedis.present? pp = placements.where( @@ -1504,7 +1484,6 @@ def ensure_consistent_placement name_id: id, parent_id: parent_id, incertae_sedis: placement_incertae_sedis, - incertae_sedis_text: incertae_sedis_text, preferred: true ).save end diff --git a/app/models/tutorial/batch.rb b/app/models/tutorial/batch.rb index 74766280..09fb983e 100644 --- a/app/models/tutorial/batch.rb +++ b/app/models/tutorial/batch.rb @@ -348,6 +348,7 @@ def batch_step_01(params, user) default_pars = { status: 0, created_by: user } param_names.each do |par| new_par = {} + placement_par = nil # Parents if par['parent'] @@ -356,12 +357,13 @@ def batch_step_01(params, user) parent = Name.new(default_pars.merge(name: par['parent'].name)) parent.save! end - new_par[:parent] = parent - new_par[:incertae_sedis] = nil + placement_par = { parent: parent, incertae_sedis: nil } elsif par['incertae_sedis'] - new_par[:parent] = nil - new_par[:incertae_sedis] = par['incertae_sedis'] - new_par[:incertae_sedis_text] = par['description'] + placement_par = { + parent: nil, + incertae_sedis: par['incertae_sedis'], + incertae_sedis_text: par['description'] + } end # Nomenclatural types @@ -384,7 +386,14 @@ def batch_step_01(params, user) name = Name.find_by_variants(par['name']) name.update!(new_par) - name.update_column(:incertae_sedis, nil) if par['incertae_sedis'] + if placement_par + placement = name.placements.find_or_initialize_by( + parent: placement_par[:parent], + incertae_sedis: placement_par[:incertae_sedis] + ) + name.placements.where.not(id: placement.id).update_all(preferred: false) + placement.update!(placement_par.merge(preferred: true)) + end end # If all is good, go to next step diff --git a/app/views/names/_taxonomy.html.erb b/app/views/names/_taxonomy.html.erb index 50c768dc..bdd14136 100644 --- a/app/views/names/_taxonomy.html.erb +++ b/app/views/names/_taxonomy.html.erb @@ -31,7 +31,7 @@ <% if @name.incertae_sedis? %>
<%= @name.incertae_sedis_html %>: - <%= @name.incertae_sedis_explain %> + <%= @name.incertae_sedis_text %>
<% elsif @name.parent %> <%= display_link(@name.parent, :name_html_correctness) %> diff --git a/app/views/registers/table.html.erb b/app/views/registers/table.html.erb index 2d86513a..f5bf1970 100644 --- a/app/views/registers/table.html.erb +++ b/app/views/registers/table.html.erb @@ -38,7 +38,7 @@ <% if name.incertae_sedis? %> <%= name.incertae_sedis_html %>: - <%= name.incertae_sedis_explain %> + <%= name.incertae_sedis_text %> <% elsif !name.parent %> Unknown <% elsif @register.names.include? name %> diff --git a/db/migrate/20260819100000_remove_incertae_sedis_from_names.rb b/db/migrate/20260819100000_remove_incertae_sedis_from_names.rb new file mode 100644 index 00000000..2d38fe1a --- /dev/null +++ b/db/migrate/20260819100000_remove_incertae_sedis_from_names.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Removes the legacy incertae sedis attributes now represented by placements. +class RemoveIncertaeSedisFromNames < ActiveRecord::Migration[6.1] + def up + execute <<~SQL.squish + DELETE FROM action_text_rich_texts + WHERE record_type = 'Name' + AND name = 'incertae_sedis_text' + SQL + + remove_column :names, :incertae_sedis, :string if column_exists?(:names, :incertae_sedis) + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/schema.rb b/db/schema.rb index b52f01d3..6f900aa0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2026_08_08_100000) do +ActiveRecord::Schema.define(version: 2026_08_19_100000) do # These are extensions that must be enabled in order to support this database enable_extension "fuzzystrmatch" @@ -234,7 +234,6 @@ t.datetime "irmng_at" t.text "col_json" t.datetime "col_at" - t.string "incertae_sedis" t.bigint "tutorial_id" t.bigint "genome_id" t.text "gbif_json" diff --git a/test/fixtures/names.yml b/test/fixtures/names.yml index 86001f60..147fc169 100644 --- a/test/fixtures/names.yml +++ b/test/fixtures/names.yml @@ -64,6 +64,26 @@ bacillales: rank: order status: 15 # SeqCode +nanobdellaceae: + name: Nanobdellaceae + rank: family + status: 15 # SeqCode + +nanoclepta_minutus: + name: Nanoclepta minutus + rank: species + status: 15 # SeqCode + +luteria_ianthellae: + name: Luteria ianthellae + rank: species + status: 15 # SeqCode + +incertae_sedis: + name: Escherichia marmotae + rank: species + status: 15 # SeqCode + type_genome_with_locations: name: Testimonas mappensis rank: species diff --git a/test/fixtures/placements.yml b/test/fixtures/placements.yml index 2488e35d..354db503 100644 --- a/test/fixtures/placements.yml +++ b/test/fixtures/placements.yml @@ -14,3 +14,8 @@ escherichia_coli: name: escherichia_coli parent: escherichia preferred: true + +incertae_sedis: + name: incertae_sedis + preferred: true + incertae_sedis: Incertae sedis (Bacteria) diff --git a/test/models/name_test.rb b/test/models/name_test.rb index 30b26064..f023e230 100644 --- a/test/models/name_test.rb +++ b/test/models/name_test.rb @@ -19,4 +19,12 @@ class NameTest < ActiveSupport::TestCase assert_includes name.errors[:register], 'must be a draft' assert_nil name.reload.register end + + test 'incertae sedis HTML comes from the preferred placement' do + name = names(:incertae_sedis) + + assert_equal( + 'Incertae sedis (Bacteria)', name.incertae_sedis_html + ) + end end From 90eda37d5aaba942acd2d1308cb132a14bd011ef Mon Sep 17 00:00:00 2001 From: vangberg Date: Tue, 8 Sep 2026 10:20:15 +0200 Subject: [PATCH 2/3] formatting --- app/controllers/placements_controller.rb | 3 ++- app/models/tutorial/batch.rb | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/placements_controller.rb b/app/controllers/placements_controller.rb index 5977e723..270c7782 100644 --- a/app/controllers/placements_controller.rb +++ b/app/controllers/placements_controller.rb @@ -125,7 +125,8 @@ def prefer @name.placement.try(:update!, preferred: false) @placement.update!(preferred: true) @name.update!( - parent: @placement.parent, assigned_in: @placement.publication + parent: @placement.parent, + assigned_in: @placement.publication ) ok = true end diff --git a/app/models/tutorial/batch.rb b/app/models/tutorial/batch.rb index 09fb983e..197ac59b 100644 --- a/app/models/tutorial/batch.rb +++ b/app/models/tutorial/batch.rb @@ -357,7 +357,10 @@ def batch_step_01(params, user) parent = Name.new(default_pars.merge(name: par['parent'].name)) parent.save! end - placement_par = { parent: parent, incertae_sedis: nil } + placement_par = { + parent: parent, + incertae_sedis: nil + } elsif par['incertae_sedis'] placement_par = { parent: nil, From f4bd5033e7667b642134aaca971be9baafa167bc Mon Sep 17 00:00:00 2001 From: vangberg Date: Tue, 8 Sep 2026 10:26:50 +0200 Subject: [PATCH 3/3] Remove misplaced incertae sedis validations from Name --- app/models/name.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/models/name.rb b/app/models/name.rb index ce71f12d..cb0b7040 100644 --- a/app/models/name.rb +++ b/app/models/name.rb @@ -128,13 +128,6 @@ class Name < ApplicationRecord message: 'can only contain letters, dashes, dots, and apostrophe' } ) - validates(:incertae_sedis, presence: true, allow_nil: true) - validates( - :incertae_sedis, absence: { - if: :parent, - message: 'cannot be declared if the parent taxon is set' - } - ) validates( :nomenclatural_type_type, presence: {