From c830624a75de4e633443155c156a5f3eebbef1ee Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Sat, 24 Oct 2026 18:08:04 +1300 Subject: [PATCH] Crop job admin --- app/controllers/admin/crop_job_templates_controller.rb | 4 ++-- app/controllers/admin/job_templates_controller.rb | 2 +- app/models/crop_job_template.rb | 4 +++- app/models/member.rb | 2 ++ app/views/admin/crop_job_templates/index.html.haml | 2 ++ app/views/admin/job_templates/index.html.haml | 2 ++ db/schema.rb | 2 +- spec/requests/admin/crop_job_templates_controller_spec.rb | 4 ++++ spec/requests/admin/job_templates_controller_spec.rb | 7 ++++++- 9 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/crop_job_templates_controller.rb b/app/controllers/admin/crop_job_templates_controller.rb index 22fabd318..4006cbbf4 100644 --- a/app/controllers/admin/crop_job_templates_controller.rb +++ b/app/controllers/admin/crop_job_templates_controller.rb @@ -10,7 +10,7 @@ module Admin before_action :set_template, only: %i(edit update destroy) def index - @templates = CropJobTemplate.where(crop_id: crop_ids).includes(:crop, :steps).order(:name) + @templates = CropJobTemplate.where(crop_id: crop_ids).includes(:crop, :creator, :steps).order(:name) end def new @@ -24,7 +24,7 @@ module Admin end def create - @template = CropJobTemplate.new(template_params) + @template = CropJobTemplate.new(template_params.merge(creator: current_member)) return render_with_another_step(:new) if add_step? if @template.save diff --git a/app/controllers/admin/job_templates_controller.rb b/app/controllers/admin/job_templates_controller.rb index ba6085581..462036479 100644 --- a/app/controllers/admin/job_templates_controller.rb +++ b/app/controllers/admin/job_templates_controller.rb @@ -9,7 +9,7 @@ module Admin def index @status = params[:status] if CropJobTemplate.statuses.key?(params[:status]) - @templates = CropJobTemplate.joins(:crop).includes(:steps, crop: :parent).order('crops.name', :name) + @templates = CropJobTemplate.joins(:crop).includes(:creator, :steps, crop: :parent).order('crops.name', :name) @templates = @templates.where(status: @status) if @status @templates = @templates.paginate(page: params[:page]) end diff --git a/app/models/crop_job_template.rb b/app/models/crop_job_template.rb index 126d81909..e842a401f 100644 --- a/app/models/crop_job_template.rb +++ b/app/models/crop_job_template.rb @@ -2,9 +2,11 @@ # A crop's suggested jobs, offered to gardeners who plant it. It belongs to the # crop it is written for and applies to that crop's varieties too. Only -# published templates are offered. +# published templates are offered. Its creator is the member who wrote it; +# templates loaded from the seed files have none. class CropJobTemplate < ApplicationRecord belongs_to :crop + belongs_to :creator, class_name: 'Member', optional: true, inverse_of: :created_crop_job_templates has_many :steps, -> { order(:position, :id) }, class_name: 'CropJobStep', dependent: :destroy, inverse_of: :crop_job_template # Which months a season is depends on the gardener's hemisphere, so it is diff --git a/app/models/member.rb b/app/models/member.rb index 238e19e67..7e98211f7 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -81,6 +81,8 @@ class Member < ApplicationRecord inverse_of: :creator has_many :created_alternate_names, class_name: 'AlternateName', foreign_key: 'creator_id', inverse_of: :creator has_many :created_scientific_names, class_name: 'ScientificName', foreign_key: 'creator_id', inverse_of: :creator + has_many :created_crop_job_templates, class_name: 'CropJobTemplate', foreign_key: 'creator_id', dependent: :nullify, + inverse_of: :creator # # Scopes diff --git a/app/views/admin/crop_job_templates/index.html.haml b/app/views/admin/crop_job_templates/index.html.haml index b18536ab8..2a47c4a6d 100644 --- a/app/views/admin/crop_job_templates/index.html.haml +++ b/app/views/admin/crop_job_templates/index.html.haml @@ -22,6 +22,7 @@ %th Name %th Applies to %th Season + %th Written by %th Steps %th Status %th @@ -31,6 +32,7 @@ %td= link_to template.name, edit_admin_crop_crop_job_template_path(@crop, template) %td= template.crop == @crop ? t('crop_job_templates.options.applies_to_all', crop: @crop.name) : t('crop_job_templates.options.applies_to_one', crop: template.crop.name) %td= crop_job_option(:season, template.season) + %td= template.creator ? link_to(template.creator, template.creator) : 'Seed data' %td= template.steps.size %td %span.badge{ class: template.published? ? 'text-bg-success' : 'text-bg-secondary' }= crop_job_option(:status, template.status) diff --git a/app/views/admin/job_templates/index.html.haml b/app/views/admin/job_templates/index.html.haml index 8d7bee11b..070484670 100644 --- a/app/views/admin/job_templates/index.html.haml +++ b/app/views/admin/job_templates/index.html.haml @@ -26,6 +26,7 @@ %th Crop %th Name %th Season + %th Written by %th Steps %th Status %tbody @@ -35,6 +36,7 @@ %td= link_to template.crop.name, admin_crop_crop_job_templates_path(crop) %td= link_to template.name, edit_admin_crop_crop_job_template_path(crop, template) %td= crop_job_option(:season, template.season) + %td= template.creator ? link_to(template.creator, template.creator) : 'Seed data' %td= template.steps.size %td - badge = template.published? ? 'text-bg-success' : 'text-bg-secondary' diff --git a/db/schema.rb b/db/schema.rb index fba27bc35..521a68788 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -545,12 +545,12 @@ ActiveRecord::Schema[8.1].define(version: 2026_10_24_100000) do create_table "crop_job_templates", force: :cascade do |t| t.datetime "created_at", null: false + t.bigint "creator_id" t.bigint "crop_id", null: false t.string "name", null: false t.string "season", default: "any", null: false t.string "status", default: "draft", null: false t.datetime "updated_at", null: false - t.bigint "creator_id" t.index ["creator_id"], name: "index_crop_job_templates_on_creator_id" t.index ["crop_id"], name: "index_crop_job_templates_on_crop_id" end diff --git a/spec/requests/admin/crop_job_templates_controller_spec.rb b/spec/requests/admin/crop_job_templates_controller_spec.rb index 81d1e9a1a..785391beb 100644 --- a/spec/requests/admin/crop_job_templates_controller_spec.rb +++ b/spec/requests/admin/crop_job_templates_controller_spec.rb @@ -57,6 +57,10 @@ describe Admin::CropJobTemplatesController do expect(crop.crop_job_templates.first).to be_draft end + it 'records who wrote it' do + expect(crop.crop_job_templates.first.creator).to eq wrangler + end + it 'goes back to the list' do expect(response).to redirect_to(admin_crop_crop_job_templates_path(crop)) end diff --git a/spec/requests/admin/job_templates_controller_spec.rb b/spec/requests/admin/job_templates_controller_spec.rb index 38cf829f1..a87906f0c 100644 --- a/spec/requests/admin/job_templates_controller_spec.rb +++ b/spec/requests/admin/job_templates_controller_spec.rb @@ -5,9 +5,10 @@ require 'rails_helper' describe Admin::JobTemplatesController do let(:tomato) { create(:crop, name: 'tomato') } let(:cherry) { create(:crop, name: 'cherry tomato', parent: tomato) } + let(:author) { create(:member, login_name: 'template_author') } before do - create(:crop_job_template, crop: tomato, name: 'Growing tomatoes', status: 'published') + create(:crop_job_template, crop: tomato, name: 'Growing tomatoes', status: 'published', creator: author) create(:crop_job_template, crop: cherry, name: 'Growing cherry tomatoes') create(:crop_job_template, name: 'Growing something else') end @@ -23,6 +24,10 @@ describe Admin::JobTemplatesController do expect(response.body).to include('Growing tomatoes', 'Growing cherry tomatoes', 'Growing something else') end + it 'shows who wrote a template' do + expect(response.body).to include('template_author') + end + it 'links a variety\'s template to its parent crop\'s templates' do expect(response.body).to include(edit_admin_crop_crop_job_template_path(tomato, cherry.crop_job_templates.first)) end