Associated Contacts with Users

Hey all,

I am still struggling to get to grips with Ruby fully and have a new problem.

I am looking to associate contacts with users through a has_many and belongs_to method. I believe I have correctly nested the contacts table as a resource of my users in routes.

At the moment however I still seem to be showing all contacts regardless of which user is signed in?

The code I currently have is :

Routes

ContactApp::Application.routes.draw do

get "sessions/new"
get "logout" => "sessions#destroy"

controller :user do
    get "signup" => "user#new"
end

resources :users, :controller => 'user', :has_many => 'contacts'

controller :sessions do
    get "login" => "sessions#new"
    post "login" => "sessions#create"
    delete "logout" => "sessions#destroy"
end

controller :dashboard do
    get "home" => "dashboard#home"
end

controller :contact do
    get "newcontact" => "contact#new"
    get "index" => "contact#index"
end

resources :contacts, :controller => 'contact'

root :to => 'sessions#new'


end

Contact Controller

class ContactController < ApplicationController
  def new
    @contact = Contact.new
  end

  def create
    @contact = Contact.new (params[:contact])
      if @contact.save
        redirect_to index_path
      else
        render "contact/new"
    end
  end

  def index
    @title= "All Users"
    @contact = Contact.all
  end
end

User Controller

class UserController < ApplicationController
  def new
	@user = User.new
  end

  def create
	@user = User.new (params[:user])
	  if @user.save
		redirect_to root_url
	  else
		render "user/new"
	end
  end
end

Contact#new Relevant part

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

	<% if @contact.errors.any? %>
		<div class="error_messages">
		 <h2>Form is invalid</h2>
			<ul>
				<% for message in @contact.errors.full_messages %>
					<li><%= message %></li>
				<% end %>
			</ul>
		</div>
	<% end %>	
	<div class = "name-field">
		<%= f.text_field :name, :placeholder => "Name" %>
	</div>
	
	<div class = "company-field">
		<%= f.text_field :company, :placeholder => "Company" %>
	</div>
	
	<div class = "email-field">
		<%= f.text_field :email, :placeholder => "Email" %>
	</div>

	<div class = "phone-field">
		<%= f.text_field :phone, :placeholder => "Phone" %>
	</div>
	
	<div class = "mobile-field">
		<%= f.text_field :mobile, :placeholder => "Mobile" %>
	</div>	
	
	<div class="actions"><%= f.submit "Add Contact" %></div>
</div>
<% end %>
</div>			
</div>

Really sorry to post yet another question on the forum but any help people can offer really would be much appreciated.

Cheers,
Tom :slight_smile:

Alright, this one is going to be a bit lengthy in explanation but I am going to do my best.

1.) Your contact model is going to need a user_id column to “tie” it to a specific user. You can add this to your app with a migration.

rails g migration AddUserIdToContacts user_id:integer

Then run rake db:migrate

2.) Your user model will need has_many :contacts and your contacts model will need belongs_to:user

3.) Your contacts controller. Here is where the magic starts. :stuck_out_tongue: First, you need to tell your create method what to save in the user_id column. Then you need to “scope” your index method so that it only displays contacts for the current user.

Here is how to achieve that:


## Business as usual for this method
def new
  @contact = Contact.new
end

## here is where we get things going
## first we find the user and store it in a variable @user
 ## current_user is our method from the application controller
## now have a contact variable that uses the user variable to store the user id plus all contact data
  def create
  @user = current_user
  @contact = @user.contacts.new(params[:contact]) 
      if @contact.save
         redirect_to root_url, :notice => "SAVED"
      else
         render "contact/new"
      end
  end
 
## again we store the current user in a variable
## and now we find all contacts that have the user id of the current user
def index
  @user = current_user
     @contacts = @user.contacts.all
  end

end

And that should get you going in the right direction. Feel free to delete all of the comments in the code, they are messy! :smiley:

Hey Scannon :slight_smile:

As always your answer has been awesome and this has worked straight away. Thanks so much for your help and I hope you have an excellent day!

Cheers,
Tom :smiley: