First question: I have a group model that belongs_to :creator, :class_name => "User"
and if the creator leaves I want someone else in the group to become the "creator". How would I do this?
As a second question, I would also like to give the leaving creator to choose a new creator when leaving, or let it be automatically assigned.
as of right now these are what my models look like:
class Group < ActiveRecord::Base
belongs_to :creator, :class_name => "User"
has_many :members, :through => :memberships
has_many :memberships, :foreign_key => "new_group_id"
and my User model:
class User < ActiveRecord::Base
has_many :groups, foreign_key: :creator_id
has_many :memberships, foreign_key: :member_id
has_many :new_groups, through: :memberships
As a third question, I would like the group to be destroyed when the creator leaves. How can I set up this kind of relation?
These are 3 questions, and the first two are quite open, so I'd try to answer all of them in order making some assumptions down the road.
First question
This depends on what do you want the behavior for choosing a new creator to be. Do you want it to be automatically assigned from the current members
? Do you want to give other members to have the change to auto-assign themselves as creator? In the latter you need to provide your members a full UI (routes, controllers, views) for that purpose, so I'll show you how would I code the first option.
First, I'd encapsulate the group leaving logic into its own method on the Group
model, that we'll use in the controller for this purpose. On Group
we define the logic for assigning as new creator
. The logic here will be to pass the method a new_creator
if we have it, or default to the first of the members
if not given.
class Group < ActiveRecord::Base
def reassign(new_creator = nil)
new_creator ||= members.first
if new_creator
self.creator = new_creator
save
else
false
end
end
end
As an alternative approach, you can move this logic into an Observer
(or any alternative) that will observe on Group
model for the attribute creator_id
to be nulled.
Second question
This one will involve a full UI that you'll need to figure out yourself according to your specifications. In short, I'd create a new action in your GroupsController
for members
to leave groups like this:
# config/routes.rb
resources :groups do
member do
get :leave
patch :reassign
end
end
# app/controllers/groups_controller.rb
class GroupsController < ApplicationController
def leave
@group = Group.find(params[:id])
end
def reassign
@group = Group.find(params[:id])
if @group.reassign(params[:new_creator_id])
redirect_to my_fancy_path
else
render :leave
end
end
end
In your views you'll have your form_for @group
with the new member candidates (possible with a select_tag :new_creator_id
) and the rest of your UI as you prefer.
Third question
This is the easiest. You just define your association like this and you'll get all User
groups destroyed after the user is deleted.
class User < ActiveRecord::Base
has_many :groups, foreign_key: :creator_id, dependent: :destroy
end