Dylan L.
Dylan L.

Reputation: 1317

requesting membership to a group mvc

I have a group model that has_many :members, and has_many :memberships. What I would like to do is make it so that in some groups the creator of the group would make it so that you have to request membership in order to join that specific group. How could I set this up in my rails application?

I have added a boolean field to the memberships ActiveRecord but I dont know how to set it up in a way that would allow me to join groups that dont require the "request a membership" function but also to create a "request a membership" function.

as of right now my models look like this:

class Group < ActiveRecord::Base

  belongs_to :creator, :class_name => "User"

  has_many :members, :through => :memberships
  has_many :memberships, :foreign_key => "new_group_id"

  has_many :events

end

class User < ActiveRecord::Base
  has_many :groups, foreign_key: :creator_id

  has_many :memberships, foreign_key: :member_id
  has_many :new_groups, through: :memberships
end

class Membership < ActiveRecord::Base
  belongs_to :member, class_name: "User"
  belongs_to :new_group, class_name: "Group"
  validates :new_group_id, uniqueness: {scope: :member_id}

  has_many :accepted_memberships, -> {where(memberships: { approved: true}) }, :through => :memberships
  has_many :pending_memberships, -> {where(memberships: { approved: false}) }, :through => :memberships
end

and my membership controller:

class MembershipsController < ApplicationController
  def create
    @group = Group.find(params[:new_group_id])
    @membership = current_user.memberships.build(:new_group_id => params[:new_group_id])
    if @membership.save
      flash[:notice] = "Joined #{@group.name} "

    else
      flash[:notice] = "You're already in this group"
    end
    redirect_to groups_url
  end

  def destroy
    @group = Group.find(params[:id])
    @membership = current_user.memberships.find_by(params[membership_id: @group.id]).destroy
    redirect_to groups_url

  end
end

Upvotes: 2

Views: 381

Answers (1)

David Lewis
David Lewis

Reputation: 168

I believe that you are already very close to your solution, and that it is more of a business problem than a technical one. First I would add a boolean to the group to indicate that approval is required. e.g.

rails generate migration add_require_approval_to_groups require_approval:boolean

This would get set when the creator first creates the group depending upon the type of group that they have created.

Now, somehow a user has to be able to discover that there are groups that they can join, and you need to communicate an awareness to them that for some groups, membership is not automatic, but must be approved by the group creator.

So, assuming that you have communicated this to the user, and that they are on a page with a selection box listing all of the groups that they can become a member of (not necessarily the best design choice, but will do for this example). You need to have a query in your model that will gather all of the available groups that a user can still join.

def self.available_groups(user_id)
 where("id not in (select group_id from group_members where user_id = ?)", user_id)
    .select("id, name")
    .collect{ |g| [g.name, g.id] }
end

In your controller:

@available_groups = Group.available_groups(@current_user)

And in your view:

<h2>Please select the group to join:</h2>
<p>
    <%= form_tag :action => 'join_group' do %>
        <%= select("group", "id",
            @available_groups) %>
        <%= submit_tag "Join" %>
    <% end %>
</p>

Now, when you process the "post" in your membership_controller, you need to inform the creator that someone is trying to join the group that requires approval (perhaps a mailer). If the require_approval boolean is not set, then you need to automatically approve the user so that they can access the group immediately.

Upvotes: 2

Related Questions