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>
This commit is contained in:
Daniel O'Connor
2026-05-12 17:23:24 +09:30
committed by GitHub
parent ca7f56683c
commit d7a50f86b5
3 changed files with 35 additions and 0 deletions

View File

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

View File

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

View File

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