Reputation: 3341
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
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
This is not the most efficient, or probably "correct" way of doing this, but should give you something to work with
Upvotes: 1
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