T. Cole
T. Cole

Reputation: 191

Rails - destroying membership/ownership in user group

I need to be able to "destroy" group ownership when I "destroy" membership of a group if a user is the owner of the group. I have "User", "Group/Cliq", and "Group/CliqMembership" models. When a user creates the group they are the "owner" of the group. Other users can then join the group. When a user leaves the group the membership association for that user and group is destroyed. However, when an owner leaves the group it only removes the "membership" and not the "ownership". I feel like there should be an easy solution, but I'm kind of stuck.

For clarity: Cliqs = Groups; the question is: how do I delete the ownership association and the membership association at the same time? When an "owner" leaves a group I want it to destroy their "group ownership" and their "group membership". As an aside: how would I make the owned group "destroy dependent" when the "owner" leaves?

Here are my models:

class Cliq < ActiveRecord::Base
 belongs_to :owner, class_name: 'User'

 has_many :cliq_memberships
 has_many :members, through: :cliq_memberships, source: :user

end

class CliqMembership < ActiveRecord::Base
 belongs_to :cliq
 belongs_to :user
end

class User < ActiveRecord::Base
 has_one :owned_cliq, foreign_key: 'owner_id', class_name: 'Cliq', dependent: :destroy

 has_many :cliq_memberships
 has_many :cliqs, through: :cliq_memberships
 .
 .
 .
end

And my controllers:

class CliqsController < ApplicationController

def show
    @cliq = Cliq.find(params[:id])
end

def new
    @cliq = Cliq.new(params[:id])
end

def create
    @cliq = current_user.build_owned_cliq(cliq_params)
    @cliq.members << current_user

    if @cliq.save
        redirect_to current_user
    else
        redirect_to new_cliq_path
    end
end

def destroy
    @cliq = current_user.owned_cliq.find(params[:id])
    flash[:alert] = "Are you sure you want to delete your Cliq? Your Cliq and all of its associations will be permanently deleted."
    @cliq.destroy

    if @cliq.destroy
       redirect_to current_user
       flash[:notice] = "You deleted the Cliq."
    else
        redirect_to current_user
        #set up error handler
        flash[:notice] = "Failed to delete Cliq."
    end
end


def cliq_params
    params.require(:cliq).permit(:name, :cliq_id)
end

class CliqMembershipsController < ApplicationController

def show
end

def create
    #Cliq or Cliq_ID?
    @cliq = Cliq.find(params[:cliq])

    @cliq_membership = current_user.cliq_memberships.build(cliq: @cliq)
    @cliq.members << current_user

    if @cliq_membership.save
        flash[:notice] = "Joined #{@cliq.name}"
    else
        #Set up multiple error message handler for rejections/already a member
        flash[:notice] = "Not able to join Cliq."
    end
    redirect_to cliq_url
end

def destroy
    @cliq_membership = current_user.cliq_memberships.find(params[:id])
    @cliq_membership.destroy

    if @cliq_membership.destroy
       flash[:notice] = "You left the Cliq."
    redirect_to user_path(current_user)

    else
    end
    end
end

class UsersController < ApplicationController

def show 
@user = User.find(params[:id])
@uploads = Upload.all
@cliq_memberships = CliqMembership.all
@cliqs = Cliq.all
end

end

Upvotes: 0

Views: 263

Answers (1)

Vishal
Vishal

Reputation: 394

In your CliqMemberships controller's destroy action, right before destroying the CliqMembership, you can check for the current_user's ownership of the group just like you're checking for his/her membership. I'm assuming you want an implementation wherein if the owner leaves the group, you want the group to automatically be destroyed too, along with all its memberships. (Correct me if I'm wrong on that.) In that case, you can add dependent: :destroy to has_many :cliq_memberships

If the current_user happens to be the owner, you can destroy the cliq altogether which would in turn destroy its cliq_memberships too.

You can do it like this in CliqMemershipsController's destroy action.

def destroy
    @cliq_membership = current_user.cliq_memberships.find(params[:id])
    @cliq = @cliq_membership.cliq
    if @cliq.owner == current_user
        @cliq.destroy
        flash[:notice] = "The Cliq is destroyed"
        redirect_to user_path(current_user)
    else
        # destroy only the membership
        flash[:notice] = "You left the Cliq."
        redirect_to user_path(current_user)
    end
end

Upvotes: 0

Related Questions