|
1 | 1 | class UpdateTermItemRelation < ActiveRecord::Migration[7.0] |
2 | 2 | def up |
3 | 3 | facet = Facet.find_by!(name: 'Decade') |
4 | | - old_term = Term.find_by!(facet: facet, value: 'After 1999') |
| 4 | + t_after_2019 = Term.find_by!(facet: facet, value: 'After 1999') |
5 | 5 |
|
6 | 6 | new_terms = { |
7 | 7 | (2000..2009) => Term.find_by!(facet: facet, value: '2000-2009'), |
8 | 8 | (2010..2019) => Term.find_by!(facet: facet, value: '2010-2019'), |
9 | 9 | (2020..) => Term.find_by!(facet: facet, value: 'After 2020') |
10 | 10 | } |
11 | 11 |
|
12 | | - old_term.items.find_each do |item| |
| 12 | + invalid_items = [] |
| 13 | + |
| 14 | + t_after_2019.items.find_each do |item| |
13 | 15 | year = integer_year(item.date) |
14 | | - next unless year |
| 16 | + unless year |
| 17 | + invalid_items << { id: item.id, date: item.date } |
| 18 | + next |
| 19 | + end |
15 | 20 |
|
16 | 21 | target_term = new_terms.find { |range, _| range.cover?(year) }&.last |
17 | 22 | next unless target_term |
18 | 23 |
|
19 | | - update_item(item, old_term, target_term) |
20 | | - end |
| 24 | + re_assign_term_to_item(item, t_after_2019, target_term) |
| 25 | + end |
| 26 | + |
| 27 | + if invalid_items.any? |
| 28 | + Rails.logger.warn("Skipped #{invalid_items.size} items due to invalid or missing dates. Example: #{invalid_items.first(10).map { |i| "ID #{i[:id]}: '#{i[:date]}'" }.join(', ')}") |
| 29 | + end |
21 | 30 | end |
22 | 31 |
|
23 | 32 | def down |
24 | 33 | facet = Facet.find_by!(name: 'Decade') |
25 | 34 | target_term = Term.find_by!(facet: facet, value: 'After 1999') |
26 | | - roll_back(facet, target_term, '2000-2009') |
27 | | - roll_back(facet, target_term, '2010-2019') |
28 | | - roll_back(facet, target_term, 'After 2020') |
| 35 | + move_term_back_to_item(facet, target_term, '2000-2009') |
| 36 | + move_term_back_to_item(facet, target_term, '2010-2019') |
| 37 | + move_term_back_to_item(facet, target_term, 'After 2020') |
29 | 38 | end |
30 | 39 |
|
31 | 40 | private |
32 | | - |
| 41 | + |
33 | 42 | def integer_year(val) |
34 | | - Integer(val) |
35 | | - rescue ArgumentError, TypeError |
36 | | - nil |
37 | | - end |
| 43 | + return nil if val.nil? |
38 | 44 |
|
39 | | - def update_item(item, origin_term, target_term) |
40 | | - return unless target_term & item & target_term |
| 45 | + # Try direct integer conversion |
| 46 | + begin |
| 47 | + return Integer(val) |
| 48 | + rescue ArgumentError, TypeError |
| 49 | + # Try to extract year from common date formats (e.g., "YYYY-MM-DD", "YYYY/MM/DD") |
| 50 | + if val.is_a?(String) |
| 51 | + if val =~ /\A(\d{4})[-\/]/ |
| 52 | + return $1.to_i |
| 53 | + end |
| 54 | + end |
| 55 | + end |
| 56 | + end |
41 | 57 |
|
42 | | - item.terms.delete(origin_term) |
| 58 | + # Reassigns an item from the origin term to the target term, and removes the origin term from the item. |
| 59 | + def re_assign_term_to_item(item, origin_term, target_term) |
43 | 60 | item.terms << target_term unless item.terms.include?(target_term) |
| 61 | + item.terms.delete(origin_term) |
44 | 62 | end |
45 | 63 |
|
46 | | - def roll_back(facet, target_term, origin_term_value) |
| 64 | + # Rolls back term assignment from origin_term_value to target_term for all items. |
| 65 | + def move_term_back_to_item(facet, target_term, origin_term_value) |
47 | 66 | origin_term = Term.find_by!(facet: facet, value: origin_term_value) |
48 | 67 | origin_term.items.find_each do |item| |
49 | | - update_item(item, origin_term, target_term) |
| 68 | + re_assign_term_to_item(item, origin_term, target_term) |
50 | 69 | end |
51 | 70 | end |
52 | 71 | end |
0 commit comments