lundi 9 janvier 2017

Ruby on Rails: Add form for another model on a form

Within my Ruby on Rails application I am trying to implement a relationship between Group and Contact, whereby one group can contain many contacts and one contact can be part of many groups. I am using a model called Contactgroup to deal with this relationship, and so the tables are:

Group (id, name)
Contact (id, firstname, surname)
Contactgroup (group_id, contact_id)

With example data being:

Groups:
ID      Name
1       Singers
2       Drummers

Contacts:
ID      Firstname    Surname
1       Freddy       Mercury
2       Roger        Taylor
3       Kurt         Cobain
4       Dave         Grohl

Contact Groups:
Group_ID        Contact_ID
1               1
1               3
1               4
2               2
2               4

What I am trying to do is get it so that when a user creates a group, they can select the contacts that they want to add to that group. This means that there is the group form, whereby the user types the group name, and on this form I want to display checkboxes for each of the user's contacts so that the user can select the contacts they want to add to the group, and when they click submit the new group will be saved in the Group table and the new contact group records will be saved in the Contactgroup table.

This is the app/views/groups/_form.html.erb code:

<%= form_for @group do |f| %>

  <% if @group.errors.any? %>
    <div id="error_explanation">
      <h2>
        <%= pluralize(@group.errors.count, "error") %> prohibited this group from being saved:
      </h2>
      <ul>
        <% @group.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <p>
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </p>

  <h2>Add members:</h2>
    <%= form_for([@group, @group.contactgroups.build]) do |f| %>
      <p>
        <%= f.collection_check_boxes(:contact_id, @contacts, :id, :firstname) %>
      </p>
      <p>
        <%= f.submit %>
      </p>
    <% end %>
  <p>
    <%= f.submit %>
  </p>

<% end %>

On here you can see the code I am trying to use to do this:

<h2>Add members:</h2>
    <%= form_for([@group, @group.contactgroups.build]) do |f| %>
      <p>
        <%= f.collection_check_boxes(:contact_id, @contacts, :id, :firstname) %>
      </p>
      <p>
        <%= f.submit %>
      </p>
    <% end %>
  <p>
    <%= f.submit %>
  </p>

<% end %>

I have got this from rails guides (http://ift.tt/IsdtVd) but I get the error undefined methodcontactgroups' for #` and don't think this will give me what I want.

My routes file is:

Rails.application.routes.draw do
  get 'sessions/new'
  get 'sessions/create'
  get 'sessions/destroy'
  resources :users
  get 'welcome/index'
  root 'welcome#index'
  resources :contacts

  resources :groups do
    resources :contactgroups
  end
  resources :contactgroups


  get 'sessions/new'
  get 'sessions/create'
  get 'sessions/destroy'
  controller :sessions do
    get  'login' => :new
    post 'login' => :create
    get 'logout' => :destroy
  end 
end

My groups_controller:

class GroupsController < ApplicationController
    def index
        @groups = Group.where(user_id: session[:user_id])
    end
    def show
        @group = Group.find(params[:id])
        @members = Contactgroup.where(group_id: @group.id)
    end
    def new
        @group = Group.new
        @contacts = Contact.where(user_id: session[:user_id])
    end
    def edit
        @group = Group.find(params[:id])
    end
    def create
        @group = Group.new(group_params)
        @group.user_id = session[:user_id]
        if @group.save
            redirect_to @group
        else
            render 'new'
        end
    end
    def update
        @group = Group.find(params[:id])
        if @group.update(group_params)
            redirect_to @group
        else
            render 'edit'
        end
    end
    def destroy
        @group = Group.find(params[:id])
        @group.destroy
        redirect_to groups_path
    end
    private
    def group_params
        params.require(:group).permit(:name, :user_id)
    end
end

And contactgroups_controller:

class ContactgroupsController < ApplicationController
    def destroy
        @contactgroup = Contactgroup.find(params[:id])
        @contactgroup.destroy
        redirect_to(:back)
    end
end

There must be a simple solution to solve this as I assume it is commonly done on other systems, but I am not sure how to do this.

Can someone please help.

Aucun commentaire:

Enregistrer un commentaire