From d7a50f86b5417868ce97bfbd707b6a804e6d2e29 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 12 May 2026 17:23:24 +0930 Subject: [PATCH] Allow collaborators to remove themselves from gardens (#4630) - Update Ability to grant destroy permission to collaborators for their own record - Add 'Leave garden' link to garden show page - Add specs for garden collaborator permissions Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- app/models/ability.rb | 1 + app/views/gardens/show.html.haml | 2 ++ .../garden_collaborator_ability_spec.rb | 32 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 spec/models/garden_collaborator_ability_spec.rb diff --git a/app/models/ability.rb b/app/models/ability.rb index 62bc7ef1e..a53c16ec8 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -123,6 +123,7 @@ class Ability can :create, GardenCollaborator, garden: { owner_id: member.id } can :update, GardenCollaborator, garden: { owner_id: member.id } can :destroy, GardenCollaborator, garden: { owner_id: member.id } + can :destroy, GardenCollaborator, member_id: member.id can :create, Activity can :update, Activity, owner_id: member.id diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index c459ae10e..02a9f66d9 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -102,6 +102,8 @@ %strong Collaborators: - if can?(:create, GardenCollaborator.new(garden: @garden)) = link_to "Manage", garden_garden_collaborators_path(@garden) + - elsif current_member.present? && (collab = @garden.garden_collaborators.find_by(member: current_member)) + = link_to "Leave garden", garden_garden_collaborator_path(@garden, collab), method: :delete, class: 'text-danger', data: { confirm: 'Are you sure you want to leave this garden?' } - if @garden.garden_collaborators.any? %ul - @garden.garden_collaborators.each do |collabator| diff --git a/spec/models/garden_collaborator_ability_spec.rb b/spec/models/garden_collaborator_ability_spec.rb new file mode 100644 index 000000000..ca321080f --- /dev/null +++ b/spec/models/garden_collaborator_ability_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'cancan/matchers' + +describe Ability do + let(:member) { create(:member) } + let(:ability) { described_class.new(member) } + + context 'garden collaborators' do + let(:garden) { create(:garden) } + let(:garden_collaborator) { create(:garden_collaborator, garden: garden, member: member) } + let(:other_member) { create(:member) } + let(:other_garden_collaborator) { create(:garden_collaborator, garden: garden, member: other_member) } + + it 'can remove themselves as a collaborator' do + expect(ability).to be_able_to(:destroy, garden_collaborator) + end + + it 'cannot remove others as a collaborator if not garden owner' do + expect(ability).not_to be_able_to(:destroy, other_garden_collaborator) + end + + context 'as garden owner' do + let(:garden) { create(:garden, owner: member) } + + it 'can remove others as a collaborator' do + expect(ability).to be_able_to(:destroy, other_garden_collaborator) + end + end + end +end