Rails 3 and Friendship models

I’m having issues creating Friendships in Rails 3 beta.

I’m following Railscast 163 (http://asciicasts.com/episodes/163-self-referential-association) and this is what I have in the relevant files:

## CONTROLLERS

application_controller.rb

class ApplicationController < ActionController::Base

def current_user

User.find(session[:user_id])

end

end

friendships_controller.rb

class FriendshipsController < ApplicationController

def create

@friendship = current_user.friendships.build(:friend_id => params[:friend_id])

if @friendship.save

flash[:notice] = ‘Added friend.’

redirect_to current_user

else

flash[:notice] = ‘Unable to add friend.’

redirect_to users_path

end

end

end

## MODELS

friendship.rb

class Friendship < ActiveRecord::Base

belongs_to :user

belongs_to :friend, :class_name => ‘User’

end

user.rb

class User < ActiveRecord::Base

has_many :friendships

has_many :friends, :through => :friendships

rest snipped for brevity

end

## VIEWS

users/index.html.haml

= link_to ‘Add Friend’, friendships_path(:friend_id => user), :method => :post

users/show.html.haml

#profile

.section

%h3= @following_title

%ul

  • if @user.friendships != []

  • for friendship in @user.friendships

%li= friendship.friend.name

  • else

%li

Nobody yet.

## OTHER

routes.rb

SampleApp::Application.routes.draw do |map|

resources :friendships

resources :sessions

resources :users do

resources :posts

end

end

xxxx_create_friendships.rb

class CreateFriendships < ActiveRecord::Migration

def self.up

create_table :friendships do |t|

t.integer :user_id

t.integer :friend_id

t.timestamps

end

end

def self.down

drop_table :friendships

end

end

The problem:

When I’m on http://localhost:3000/users/ and I try to ‘Add Friend’ user_3 (which should POST with http://localhost:3000/friendships?friend_id=3), I get the following page:

Unknown action

The action ‘index’ could not be found

It’s clearly because there isn’t a ‘friendships/index’ page. However, I don’t understand why the application is even trying to reach ‘friendships/index’. The code should be redirecting the current user to their profile page after the friendship is created.

When I manually go to the current user’s profile page, I see that no friendships are listed–which means that my code for ‘Add Friend’ isn’t saving the friendship to the database either.

I’m probably missing something very simple, but I’m very new to Rails. Thanks in advance for any help.

Try doing

rake routes

to see what friendships_path is. Betcha it is FriendshipsController#index

This is what I have for rake routes. It looks like friendships_path is FriendshipsController#index (like you said), but with :method => :post it should link to FriendshipsController#create?

It looks like GET is happening instead of POST.

GET /friendships(.:format) {:controller=>“friendships”, :action=>“index”}

friendships POST /friendships(.:format) {:controller=>“friendships”, :action=>“create”}

new_friendship GET /friendships/new(.:format) {:controller=>“friendships”, :action=>“new”}

GET /friendships/:id(.:format) {:controller=>“friendships”, :action=>“show”}

PUT /friendships/:id(.:format) {:controller=>“friendships”, :action=>“update”}

friendship DELETE /friendships/:id(.:format) {:controller=>“friendships”, :action=>“destroy”}

edit_friendship GET /friendships/:id/edit(.:format) {:controller=>“friendships”, :action=>“edit”}

GET /sessions(.:format) {:controller=>“sessions”, :action=>“index”}

sessions POST /sessions(.:format) {:controller=>“sessions”, :action=>“create”}

new_session GET /sessions/new(.:format) {:controller=>“sessions”, :action=>“new”}

GET /sessions/:id(.:format) {:controller=>“sessions”, :action=>“show”}

PUT /sessions/:id(.:format) {:controller=>“sessions”, :action=>“update”}

session DELETE /sessions/:id(.:format) {:controller=>“sessions”, :action=>“destroy”}

edit_session GET /sessions/:id/edit(.:format) {:controller=>“sessions”, :action=>“edit”}

GET /users/:user_id/posts/:post_id/comments(.:format) {:controller=>“comments”, :action=>“index”}

user_post_comments POST /users/:user_id/posts/:post_id/comments(.:format) {:controller=>“comments”, :action=>“create”}

new_user_post_comment GET /users/:user_id/posts/:post_id/comments/new(.:format) {:controller=>“comments”, :action=>“new”}

GET /users/:user_id/posts/:post_id/comments/:id(.:format) {:controller=>“comments”, :action=>“show”}

PUT /users/:user_id/posts/:post_id/comments/:id(.:format) {:controller=>“comments”, :action=>“update”}

user_post_comment DELETE /users/:user_id/posts/:post_id/comments/:id(.:format) {:controller=>“comments”, :action=>“destroy”}

edit_user_post_comment GET /users/:user_id/posts/:post_id/comments/:id/edit(.:format) {:controller=>“comments”, :action=>“edit”}

GET /users/:user_id/posts(.:format) {:controller=>“posts”, :action=>“index”}

user_posts POST /users/:user_id/posts(.:format) {:controller=>“posts”, :action=>“create”}

new_user_post GET /users/:user_id/posts/new(.:format) {:controller=>“posts”, :action=>“new”}

GET /users/:user_id/posts/:id(.:format) {:controller=>“posts”, :action=>“show”}

PUT /users/:user_id/posts/:id(.:format) {:controller=>“posts”, :action=>“update”}

user_post DELETE /users/:user_id/posts/:id(.:format) {:controller=>“posts”, :action=>“destroy”}

edit_user_post GET /users/:user_id/posts/:id/edit(.:format) {:controller=>“posts”, :action=>“edit”}

GET /users(.:format) {:controller=>“users”, :action=>“index”}

users POST /users(.:format) {:controller=>“users”, :action=>“create”}

new_user GET /users/new(.:format) {:controller=>“users”, :action=>“new”}

GET /users/:id(.:format) {:controller=>“users”, :action=>“show”}

PUT /users/:id(.:format) {:controller=>“users”, :action=>“update”}

user DELETE /users/:id(.:format) {:controller=>“users”, :action=>“destroy”}

edit_user GET /users/:id/edit(.:format) {:controller=>“users”, :action=>“edit”}

signup /signup {:controller=>“users”, :action=>“new”}

login /login {:controller=>“sessions”, :action=>“new”}

logout /logout {:controller=>“sessions”, :action=>“destroy”}

help /help {:controller=>“pages”, :action=>“help”}

about /about {:controller=>“pages”, :action=>“about”}

contact /contact {:controller=>“pages”, :action=>“contact”}

root / {:controller=>“pages”, :action=>“index”}

When I try to add user_3 as a friend using the following code:

= link_to ‘Add Friend’, friendships_path(:friend_id => user), :method => :post
#=> which generates http://localhost:3000/friendships?friend_id=3

This is what happens in my server console:

Started GET “/friendships?friend_id=3” for 127.0,0,1 at 2010-03-05 00:37:45

AbstractController::ActionNotFound (the action ‘index’ could not be found):

It looks like Rails is ignoring my :method => :post parameter.

There is a bug in prototype.js, therefore method handler dont work
correctly in rails.js
Try to install latest prototype from repository or use jquery.

https://rails.lighthouseapp.com/projects/8994/tickets/4013-link_to-with-method-doesnt-work

Rakoth, awesome detective work. Friend-adding seems to be working now.