Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions db/migrate/20250930215317_add_two_terms.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Migration to add "Digital" and "Drawing" terms to the "Medium" facet.
class AddTwoTerms < ActiveRecord::Migration[7.0]
def up
facet = Facet.find_by!(name: "Medium")
Term.create!(facet: facet, value: "Digital")
Term.create!(facet: facet, value: "Drawing")
end

def down
facet = Facet.find_by!(name: "Medium")
Term.where(facet: facet, value: ["Digital", "Drawing"]).delete_all
end
end
36 changes: 36 additions & 0 deletions db/migrate/20250930220140_add_three_ordered_terms.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Migration summary:
# After running `up`, the "Decade" facet will have terms:
# - "2000-2009" (ord: 11)
# - "2010-2019" (ord: 12)
# - "After 2020" (ord: 13)
# - "No Date" (ord: 14)
# - "After 1999" (ord: 15, to be removed after updating items_terms)
# After running `down`, the "Decade" facet will have:
# - "No Date" (ord: 12)
# - "After 1999" (ord: 11)
# - The three new terms will be deleted.

class AddThreeOrderedTerms < ActiveRecord::Migration[7.0]
def up
facet = Facet.find_by!(name: "Decade")
term = Term.find_by!(facet: facet, value: "After 1999")
# NOTE: Ensure all related items_terms records are updated before removing "After 1999" to prevent orphaned references.
term.update!(ord: 15)
term = Term.find_by!(facet: facet, value: "No Date")
term.update!(ord: 14)

Term.create!(facet: facet, value: "2000-2009", ord: 11)
Term.create!(facet: facet, value: "2010-2019", ord: 12)
Term.create!(facet: facet, value: "After 2020",ord: 13)
end

def down
facet = Facet.find_by!(name: "Decade")
Term.where(facet: facet, value: ["2000-2009", "2010-2019", "After 2020"]).delete_all
term = Term.find_by!(facet: facet, value: "After 1999")
term.update!(ord: 11)
term = Term.find_by!(facet: facet, value: "No Date")
term.update!(ord: 12)
end
end

74 changes: 74 additions & 0 deletions db/migrate/20250930220504_update_term_item_relation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Migration to reassign items with the term "After 1999" to a newly categorized term.
class UpdateTermItemRelation < ActiveRecord::Migration[7.0]
def up
facet = Facet.find_by!(name: 'Decade')
t_after_2019 = Term.find_by!(facet: facet, value: 'After 1999')

new_terms = {
(2000..2009) => Term.find_by!(facet: facet, value: '2000-2009'),
(2010..2019) => Term.find_by!(facet: facet, value: '2010-2019'),
(2020..) => Term.find_by!(facet: facet, value: 'After 2020')
}

invalid_items = []

t_after_2019.items.find_each do |item|
year = integer_year(item.date)
unless year
invalid_items << { id: item.id, date: item.date }
next
end

target_term = new_terms.find { |range, _| range.cover?(year) }&.last
next unless target_term

re_assign_term_to_item(item, t_after_2019, target_term)
end

if invalid_items.any?
Rails.logger.warn("Skipped #{invalid_items.size} items due to invalid or missing dates. Example: #{invalid_items.first(5).map { |i| "ID #{i[:id]}: '#{i[:date]}'" }.join(', ')}")
end
end

def down
facet = Facet.find_by!(name: 'Decade')
target_term = Term.find_by!(facet: facet, value: 'After 1999')
revert_term_assignment(facet, '2000-2009', target_term)
revert_term_assignment(facet, '2010-2019', target_term)
revert_term_assignment(facet, 'After 2020', target_term)
end

private

def integer_year(val)
return nil if val.nil?

# Try direct integer conversion
year = nil
begin
year = Integer(val)
rescue ArgumentError, TypeError
# Try to extract year from common date formats (e.g., "YYYY-MM-DD", "YYYY/MM/DD")
if val.is_a?(String)
if val =~ /\A(\d{4})[-\/]/
year = $1.to_i
end
end
end
return year
end

# Reassigns an item from the origin term to the target term, and removes the origin term from the item.
def re_assign_term_to_item(item, origin_term, target_term)
item.terms << target_term
item.terms.delete(origin_term)
end

# Rolls back term assignment from origin_term_value to target_term for all items.
def revert_term_assignment(facet, origin_term_value, target_term)
origin_term = Term.find_by!(facet: facet, value: origin_term_value)
origin_term.items.find_each do |item|
re_assign_term_to_item(item, origin_term, target_term)
end
end
end
47 changes: 47 additions & 0 deletions db/migrate/20250930230620_update_fix_term_item_relation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Migration to update three items with nil or invalid date/year values
class UpdateFixTermItemRelation < ActiveRecord::Migration[7.0]
def up
facet = Facet.find_by!(name: 'Decade')
t_after_1999 = Term.find_by!(facet: facet, value: 'After 1999')
t2000_2009 = Term.find_by!(facet: facet, value: '2000-2009')
t2020_plus = Term.find_by!(facet: facet, value: 'After 2020')

# Items with nil date
update_item_term(t_after_1999.id, t2000_2009.id, "i.date is null AND i.title in ('Loading a Cannon', 'Dense Populations')")
# Items with date = '[2020]'
update_item_term(t_after_1999.id, t2020_plus.id, "date = '[2020]'")
end

def down
facet = Facet.find_by!(name: 'Decade')
t_after_1999 = Term.find_by!(facet: facet, value: 'After 1999')
t2000_2009 = Term.find_by!(facet: facet, value: '2000-2009')
t2020_plus = Term.find_by!(facet: facet, value: 'After 2020')

# revert items with nil date
update_item_term(t2000_2009.id,t_after_1999.id, "i.date is null AND i.title in ('Loading a Cannon', 'Dense Populations')")
# revert items with date = '[2020]'
update_item_term(t2020_plus.id, t_after_1999.id, "date = '[2020]'")
end

private

def update_item_term(old_term_id, new_term_id, condition_sql)

execute <<~SQL.squish
WITH target AS (
SELECT it.term_id, it.item_id
FROM items i
JOIN items_terms it ON i.id = it.item_id
JOIN terms t ON it.term_id = t.id
WHERE t.id = #{old_term_id}
AND #{condition_sql}
)
UPDATE items_terms it
SET term_id = #{new_term_id}
FROM target
WHERE it.item_id = target.item_id
AND it.term_id = target.term_id;
SQL
end
end
11 changes: 11 additions & 0 deletions db/migrate/20251001223022_delete_term_after1999.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class DeleteTermAfter1999 < ActiveRecord::Migration[7.0]
def up
facet = Facet.find_by!(name: 'Decade')
exec_delete("DELETE FROM terms WHERE facet_id = #{facet.id} and value = 'After 1999' and ord = 15")
end

def down
facet = Facet.find_by!(name: 'Decade')
Term.create!(facet: facet, value: "After 1999", ord: 15)
end
end
2 changes: 1 addition & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2022_12_08_181611) do
ActiveRecord::Schema[7.0].define(version: 2025_10_01_223022) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down
Loading