|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +class Admin::PersonMergesController < Admin::BaseController |
| 4 | + CANDIDATE_LIMIT = 20 |
| 5 | + |
| 6 | + before_action :set_source_person, only: [ :new, :preview, :create ] |
| 7 | + before_action :set_target_person, only: [ :preview, :create ] |
| 8 | + |
| 9 | + def active_admin_section |
| 10 | + :person_merges |
| 11 | + end |
| 12 | + |
| 13 | + def index |
| 14 | + @person_merges = PersonMerge.includes(:performed_by).order(created_at: :desc).limit(100) |
| 15 | + end |
| 16 | + |
| 17 | + def new |
| 18 | + @target_query = params[:target_q].to_s.strip |
| 19 | + @candidates = if @target_query.present? |
| 20 | + Person.matching(@target_query) |
| 21 | + .where.not(id: @source_person.id) |
| 22 | + .includes(:aliases, :default_alias, :user) |
| 23 | + .limit(CANDIDATE_LIMIT) |
| 24 | + else |
| 25 | + Person.none |
| 26 | + end |
| 27 | + end |
| 28 | + |
| 29 | + def preview |
| 30 | + return redirect_to_new_with_error("Target person is required") unless @target_person |
| 31 | + |
| 32 | + error = service.validation_error |
| 33 | + return redirect_to_new_with_error(error) if error |
| 34 | + |
| 35 | + @preview = service.preview |
| 36 | + end |
| 37 | + |
| 38 | + def create |
| 39 | + return redirect_to_new_with_error("Target person is required") unless @target_person |
| 40 | + |
| 41 | + result = service.call |
| 42 | + |
| 43 | + if result.success? |
| 44 | + redirect_to admin_people_path, |
| 45 | + notice: "Merged #{result.person_merge.source_name} into #{result.person_merge.target_name}." |
| 46 | + else |
| 47 | + redirect_to_new_with_error(result.error) |
| 48 | + end |
| 49 | + end |
| 50 | + |
| 51 | + private |
| 52 | + |
| 53 | + def service |
| 54 | + @service ||= PersonMergeService.new( |
| 55 | + source_person: @source_person, |
| 56 | + target_person: @target_person, |
| 57 | + merged_by: current_user |
| 58 | + ) |
| 59 | + end |
| 60 | + |
| 61 | + def set_source_person |
| 62 | + @source_person = Person.find(params[:person_id]) |
| 63 | + rescue ActiveRecord::RecordNotFound |
| 64 | + redirect_to admin_people_path, alert: "Source person not found" |
| 65 | + end |
| 66 | + |
| 67 | + def set_target_person |
| 68 | + target_id = params[:target_person_id].presence |
| 69 | + @target_person = Person.find_by(id: target_id) if target_id |
| 70 | + end |
| 71 | + |
| 72 | + def redirect_to_new_with_error(message) |
| 73 | + redirect_to new_admin_person_merge_path(@source_person), alert: message |
| 74 | + end |
| 75 | +end |
0 commit comments