2

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.

Community
  • 1
  • 1
thanos
  • 3,203
  • 4
  • 18
  • 27

2 Answers2

1

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

Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • This is just perfect...I love detail. Thank you so much. I'll try it now now! – thanos Jul 29 '14 at 09:07
  • No problem! Could have errors, so if you let me know the problems, we can work through them – Richard Peck Jul 29 '14 at 09:18
  • Thanks for helping me :) So I replaced the current code with your (nicer) code, I created a few groups in the console and have them displaying, I get GroupController uninitialized error, but we have a group controller no? So I suppose it worked cause I haven't created the view for the groups yet? – thanos Jul 29 '14 at 09:20
  • 1
    To test out the Join groups feature, I wrote the following in a view:`<%= Group.all.each do |each_group| %>` `
    ` `<%= each_group.group_name %> `<%= link_to "Join this group", join_group_path(each_group) %>` `
    ` `
    ` `<% end %>` I really hate this formatting
    – thanos Jul 29 '14 at 09:22
  • 1 comment to add - the membership controller should reference for membership.new: `{group: @group}` – Brett Feb 27 '23 at 23:07
0

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)
Edward
  • 1,914
  • 13
  • 26
  • I see, that makes sense. With that particular code in the second post, I was trying to modify it to fit my scenario. I was only creating groups in the console and trying to join them via the view (I don't know the controller actions to create the group from the view at the moment). – thanos Jul 29 '14 at 06:17
  • Could you help me with the controller action for creating a group? I can do this in the Rails console manually, but I can't figure out the controller action. – thanos Jul 29 '14 at 07:41
  • In your controller try to check @group.nil? and @membership.nil? using logger.debug to confirm if the problem actually originates from that. – Edward Jul 29 '14 at 14:51