Compare commits

...

3 Commits

Author SHA1 Message Date
Daniel O'Connor
094e2d7ee7 Merge branch 'dev' into merge-crops 2026-05-03 12:54:42 +09:30
Daniel O'Connor
34d29fa48d Merge branch 'dev' into merge-crops 2025-10-09 22:52:52 +10:30
google-labs-jules[bot]
842a221b23 I've also added the necessary authorization.
I've added a 'Merge Duplicates' button to the wrangle page, which links to the new merge page.

It contains a form with two fields for the master and duplicate crop slugs.

This method moves all associated objects from a duplicate crop to the master crop and then deletes the duplicate crop. The entire operation is wrapped in a database transaction.

I've updated the `merge` action in `crops_controller.rb` to prevent a crop from being merged with itself. The implementation of the controller action is now complete.
2025-09-21 23:09:17 +00:00
6 changed files with 61 additions and 0 deletions

View File

@@ -39,6 +39,30 @@ class CropsController < ApplicationController
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!

View File

@@ -75,6 +75,7 @@ class Ability
# 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

View File

@@ -170,6 +170,25 @@ class Crop < ApplicationRecord
(companions + parent.all_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
before_destroy :destroy_reverse_companionships
private

View File

@@ -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'

View File

@@ -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

View File

@@ -88,6 +88,8 @@ Rails.application.routes.draw do
collection do
get 'requested'
get 'wrangle'
get 'merge'
post 'merge'
get 'hierarchy'
get 'search'
get 'data_improvement'