thanos
thanos

Reputation: 3341

RubyOnRails - Users joining Groups through Memberships

I'm still a new to Rails, so I'm finding this so frustrating. I'm trying to make a small application as part of a personal project that lets users create and join each others groups.

I've looked on StackOverflow and found two similar questions with answers that don't quite address my scenario (I've even tried using their code and still can't figure out how to go about this).

Those SO links are here:

How do I create a join action between a group and a user?

creating a join action between user and group correctly

What I'm trying to do is figure out the controller actions and erb code that lets users create and join groups. Here are two posts on SO that I've read repeatedly, I tried using their code at one point, but kept getting a

First argument in form cannot contain nil or be empty

for

<%= form_for(@membership) do |f| %>

That error came from when I was using the membership_controller code in the second SO post I listed. Here are the models I have so far, which I wrote with some help from SO as well.

user.rb (model)

class User < ActiveRecord::Base
    has_many :memberships, :dependent => :destroy
    has_many :groups, :through => :memberships

membership.rb (model)

class Membership < ActiveRecord::Base
    attr_accessible :user_id, :group_id
    belongs_to :user
    belongs_to :group 

group.rb (model)

class Group < ActiveRecord::Base
    has_many :memberships, :dependent => :destroy
    has_many :users, :through => :memberships

I honestly can't figure out how to connect these three models, I've seen examples, tried to think of it for myself for more than a few hours now.

If you can help at all, I will greatly appreciate it. I'm just pulling my hair out trying to get something that I know is simple to do in Rails to work properly.

Upvotes: 2

Views: 1353

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

I'll just detail what I would do:


#config/routes.rb
resources :groups, only: [:show], shallow: true do
   resources :memberships, only: [:new] #-> domain.com/2/memberships/new
end

This will send you to the memberships controller, which you can look like this:

#app/controllers/memberships_controller.rb
Class MembershipsController < ApplicationController
    def new
      @group = Group.find params[:group_id]
      @membership = Membership.new({group: group})
    end

    def create
      @group = Group.find params[:group_id]
      @membership = Membership.new(membership_params)
    end

    private

    def membership_params
        params.require(:membership).merge(group_id: params[:group_id], user_id: current_user.id)
    end
end

This will allow you to create the following form:

#app/views/memberships/new.html.erb
<% if user_signed_in? %>
   <% if current_user.groups.include?(@group) %>
       You're already a member of this group!
   <% else %>
      <%= form_for [@group, @membership] do |f| %>
         <%= f.submit "Join" %>
      <% end %>
   <% end %>
<% end %>

--

You'll have your models set up with as has_many :through association (allowing you to directly affect the join model):

#app/models/user.rb
Class User < ActiveRecord::Base
   has_many :memberships
   has_many :groups, through: :memberships
end

#app/models/membership.rb
Class Membership < ActiveRecord::Base
   belongs_to :group
   belongs_to :user
end

#app/models/group.rb
Class Group < ActiveRecord::Base
   has_many :memberships
   has_many :users, through: :memberships
end

enter image description here


This is not the most efficient, or probably "correct" way of doing this, but should give you something to work with

Upvotes: 1

Edward
Edward

Reputation: 1914

The error message implies that @membership is nil or []. You should check the following lines to see why that happened. Possibly @group does not exist

@group = Group.find_by_name(:group)
@membership = current_user.memberships.build(:group_id => @group.group_id)

Upvotes: 0

Related Questions