diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 8a76566d06..dd719dcbc4 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -39,6 +39,30 @@ def wrangle respond_with @crops end + def merge + authorize! :merge, Crop + if request.post? + master_crop = Crop.find_by(slug: params[:master_crop_slug]) + duplicate_crop = Crop.find_by(slug: params[:duplicate_crop_slug]) + + if master_crop && duplicate_crop + if master_crop == duplicate_crop + flash[:alert] = "You cannot merge a crop with itself." + render :merge + else + master_crop.merge_with(duplicate_crop) + flash[:notice] = "Successfully merged #{duplicate_crop.name} into #{master_crop.name}." + redirect_to wrangle_crops_path + end + else + flash[:alert] = "Could not find one of the crops." + render :merge + end + else + # GET request, just render the form + end + end + def gbif @crop = Crop.find(params[:crop_slug]) @crop.update_gbif_data! diff --git a/app/models/ability.rb b/app/models/ability.rb index 4bce190855..cdcf7d71c7 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -75,6 +75,7 @@ def member_abilities(member) # only crop wranglers can create/edit/destroy crops if member.role? :crop_wrangler can :wrangle, Crop + can :merge, Crop can :manage, Crop can :manage, CropCompanion can :manage, ScientificName diff --git a/app/models/crop.rb b/app/models/crop.rb index a647c766f2..fac3b22743 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -159,6 +159,25 @@ def all_companions (companions + parent.companions).uniq end + def merge_with(other_crop) + Crop.transaction do + other_crop.alternate_names.update_all(crop_id: id) + other_crop.scientific_names.update_all(crop_id: id) + other_crop.plantings.update_all(crop_id: id) + other_crop.seeds.update_all(crop_id: id) + other_crop.harvests.update_all(crop_id: id) + other_crop.photo_associations.update_all(crop_id: id) + other_crop.varieties.update_all(parent_id: id) + other_crop.crop_posts.update_all(crop_id: id) + + # Companions can be crop_a or crop_b + CropCompanion.where(crop_a_id: other_crop.id).update_all(crop_a_id: id) + CropCompanion.where(crop_b_id: other_crop.id).update_all(crop_b_id: id) + + other_crop.destroy + end + end + private def count_uses_of_property(col_name) diff --git a/app/views/crops/merge.html.haml b/app/views/crops/merge.html.haml new file mode 100644 index 0000000000..1907b889ee --- /dev/null +++ b/app/views/crops/merge.html.haml @@ -0,0 +1,14 @@ +- content_for :title, "Merge Crops" + +%h1 Merge Crops + += form_tag merge_crops_path, method: :post do + .form-group + = label_tag :master_crop_slug, "Master Crop (the one to keep)" + = text_field_tag :master_crop_slug, nil, class: 'form-control' + + .form-group + = label_tag :duplicate_crop_slug, "Duplicate Crop (the one to delete)" + = text_field_tag :duplicate_crop_slug, nil, class: 'form-control' + + = submit_tag "Merge", class: 'btn btn-primary' diff --git a/app/views/crops/wrangle.html.haml b/app/views/crops/wrangle.html.haml index caef0cdf7b..d8ed005b29 100644 --- a/app/views/crops/wrangle.html.haml +++ b/app/views/crops/wrangle.html.haml @@ -4,6 +4,7 @@ %nav.nav = link_to "Full crop hierarchy", hierarchy_crops_path, class: 'nav-link' + = link_to "Merge Duplicates", merge_crops_path, class: 'btn' = link_to "Add Crop", new_crop_path, class: 'btn' %section.crop_wranglers diff --git a/config/routes.rb b/config/routes.rb index 0cb18fb3f0..74eea03e3b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -87,6 +87,8 @@ collection do get 'requested' get 'wrangle' + get 'merge' + post 'merge' get 'hierarchy' get 'search' end