Skip to content

Commit 809f4ee

Browse files
authored
Ap 427 - GALC: modify filters and database options (#16)
* Add migrations for AP-427 * Change variable names * Update variable name * Add comments and update some functions * Fix the special items * Push the schema.rb with latest migration timestamp * Drop term After 1999 * Update some methods * Add comments * Add comments, improve performace etc. * Add comments * Rename migration
1 parent d895ff4 commit 809f4ee

6 files changed

+182
-1
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Migration to add "Digital" and "Drawing" terms to the "Medium" facet.
2+
class AddTwoTerms < ActiveRecord::Migration[7.0]
3+
def up
4+
facet = Facet.find_by!(name: "Medium")
5+
Term.create!(facet: facet, value: "Digital")
6+
Term.create!(facet: facet, value: "Drawing")
7+
end
8+
9+
def down
10+
facet = Facet.find_by!(name: "Medium")
11+
Term.where(facet: facet, value: ["Digital", "Drawing"]).delete_all
12+
end
13+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Migration summary:
2+
# After running `up`, the "Decade" facet will have terms:
3+
# - "2000-2009" (ord: 11)
4+
# - "2010-2019" (ord: 12)
5+
# - "After 2020" (ord: 13)
6+
# - "No Date" (ord: 14)
7+
# - "After 1999" (ord: 15, to be removed after updating items_terms)
8+
# After running `down`, the "Decade" facet will have:
9+
# - "No Date" (ord: 12)
10+
# - "After 1999" (ord: 11)
11+
# - The three new terms will be deleted.
12+
13+
class AddThreeOrderedTerms < ActiveRecord::Migration[7.0]
14+
def up
15+
facet = Facet.find_by!(name: "Decade")
16+
term = Term.find_by!(facet: facet, value: "After 1999")
17+
# NOTE: Ensure all related items_terms records are updated before removing "After 1999" to prevent orphaned references.
18+
term.update!(ord: 15)
19+
term = Term.find_by!(facet: facet, value: "No Date")
20+
term.update!(ord: 14)
21+
22+
Term.create!(facet: facet, value: "2000-2009", ord: 11)
23+
Term.create!(facet: facet, value: "2010-2019", ord: 12)
24+
Term.create!(facet: facet, value: "After 2020",ord: 13)
25+
end
26+
27+
def down
28+
facet = Facet.find_by!(name: "Decade")
29+
Term.where(facet: facet, value: ["2000-2009", "2010-2019", "After 2020"]).delete_all
30+
term = Term.find_by!(facet: facet, value: "After 1999")
31+
term.update!(ord: 11)
32+
term = Term.find_by!(facet: facet, value: "No Date")
33+
term.update!(ord: 12)
34+
end
35+
end
36+
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Migration to reassign items with the term "After 1999" to a newly categorized term.
2+
class UpdateTermItemRelation < ActiveRecord::Migration[7.0]
3+
def up
4+
facet = Facet.find_by!(name: 'Decade')
5+
t_after_2019 = Term.find_by!(facet: facet, value: 'After 1999')
6+
7+
new_terms = {
8+
(2000..2009) => Term.find_by!(facet: facet, value: '2000-2009'),
9+
(2010..2019) => Term.find_by!(facet: facet, value: '2010-2019'),
10+
(2020..) => Term.find_by!(facet: facet, value: 'After 2020')
11+
}
12+
13+
invalid_items = []
14+
15+
t_after_2019.items.find_each do |item|
16+
year = integer_year(item.date)
17+
unless year
18+
invalid_items << { id: item.id, date: item.date }
19+
next
20+
end
21+
22+
target_term = new_terms.find { |range, _| range.cover?(year) }&.last
23+
next unless target_term
24+
25+
re_assign_term_to_item(item, t_after_2019, target_term)
26+
end
27+
28+
if invalid_items.any?
29+
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(', ')}")
30+
end
31+
end
32+
33+
def down
34+
facet = Facet.find_by!(name: 'Decade')
35+
target_term = Term.find_by!(facet: facet, value: 'After 1999')
36+
revert_term_assignment(facet, '2000-2009', target_term)
37+
revert_term_assignment(facet, '2010-2019', target_term)
38+
revert_term_assignment(facet, 'After 2020', target_term)
39+
end
40+
41+
private
42+
43+
def integer_year(val)
44+
return nil if val.nil?
45+
46+
# Try direct integer conversion
47+
year = nil
48+
begin
49+
year = Integer(val)
50+
rescue ArgumentError, TypeError
51+
# Try to extract year from common date formats (e.g., "YYYY-MM-DD", "YYYY/MM/DD")
52+
if val.is_a?(String)
53+
if val =~ /\A(\d{4})[-\/]/
54+
year = $1.to_i
55+
end
56+
end
57+
end
58+
return year
59+
end
60+
61+
# Reassigns an item from the origin term to the target term, and removes the origin term from the item.
62+
def re_assign_term_to_item(item, origin_term, target_term)
63+
item.terms << target_term
64+
item.terms.delete(origin_term)
65+
end
66+
67+
# Rolls back term assignment from origin_term_value to target_term for all items.
68+
def revert_term_assignment(facet, origin_term_value, target_term)
69+
origin_term = Term.find_by!(facet: facet, value: origin_term_value)
70+
origin_term.items.find_each do |item|
71+
re_assign_term_to_item(item, origin_term, target_term)
72+
end
73+
end
74+
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Migration to update three items with nil or invalid date/year values
2+
class UpdateFixTermItemRelation < ActiveRecord::Migration[7.0]
3+
def up
4+
facet = Facet.find_by!(name: 'Decade')
5+
t_after_1999 = Term.find_by!(facet: facet, value: 'After 1999')
6+
t2000_2009 = Term.find_by!(facet: facet, value: '2000-2009')
7+
t2020_plus = Term.find_by!(facet: facet, value: 'After 2020')
8+
9+
# Items with nil date
10+
update_item_term(t_after_1999.id, t2000_2009.id, "i.date is null AND i.title in ('Loading a Cannon', 'Dense Populations')")
11+
# Items with date = '[2020]'
12+
update_item_term(t_after_1999.id, t2020_plus.id, "date = '[2020]'")
13+
end
14+
15+
def down
16+
facet = Facet.find_by!(name: 'Decade')
17+
t_after_1999 = Term.find_by!(facet: facet, value: 'After 1999')
18+
t2000_2009 = Term.find_by!(facet: facet, value: '2000-2009')
19+
t2020_plus = Term.find_by!(facet: facet, value: 'After 2020')
20+
21+
# revert items with nil date
22+
update_item_term(t2000_2009.id,t_after_1999.id, "i.date is null AND i.title in ('Loading a Cannon', 'Dense Populations')")
23+
# revert items with date = '[2020]'
24+
update_item_term(t2020_plus.id, t_after_1999.id, "date = '[2020]'")
25+
end
26+
27+
private
28+
29+
def update_item_term(old_term_id, new_term_id, condition_sql)
30+
31+
execute <<~SQL.squish
32+
WITH target AS (
33+
SELECT it.term_id, it.item_id
34+
FROM items i
35+
JOIN items_terms it ON i.id = it.item_id
36+
JOIN terms t ON it.term_id = t.id
37+
WHERE t.id = #{old_term_id}
38+
AND #{condition_sql}
39+
)
40+
UPDATE items_terms it
41+
SET term_id = #{new_term_id}
42+
FROM target
43+
WHERE it.item_id = target.item_id
44+
AND it.term_id = target.term_id;
45+
SQL
46+
end
47+
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class DeleteTermAfter1999 < ActiveRecord::Migration[7.0]
2+
def up
3+
facet = Facet.find_by!(name: 'Decade')
4+
exec_delete("DELETE FROM terms WHERE facet_id = #{facet.id} and value = 'After 1999' and ord = 15")
5+
end
6+
7+
def down
8+
facet = Facet.find_by!(name: 'Decade')
9+
Term.create!(facet: facet, value: "After 1999", ord: 15)
10+
end
11+
end

db/schema.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

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

0 commit comments

Comments
 (0)