Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Naomi Freeman
STAFF
Naomi Freeman
Treehouse Guest Teacher

Error accepting friendships

I am working on the social features in the Treebook project. My friendships were coming along fine, if a little quirky right up until the final step, where you set the code to "accept" the friendship. All the pieces of the process work, until that mutual_friendship thing is supposed to happen.

I think the problem may be that the methods aren't available to an other class. Any thoughts on how I'd fix that? With @, but where?

If you think it's something else entirely, do let me know. Thanks!

Here's my error: (please note the code it is showing the error for is NOT in the UserFriendshipsController, but is in the user_friendships model)

NoMethodError in UserFriendshipsController#accept undefined method `accept_mutual_friendship?' for #<UserFriendship:0x00000103b72c68>

Extracted source (around line #10): 8 9 10 11 12 13 def accept @user_friendship = current_user.user_friendships.find(params[:id]) if @user_friendship.accept_mutual_friendship? flash[:success] = "You are now friends with # {@user_friendship.user.first_name}!" else flash[:error] = "They think you're a creep."

Rails.root: /Users/naomifreeman/Projects/laughing-wookie

Application Trace | Framework Trace | Full Trace app/controllers/user_friendships_controller.rb:10:in `accept' Request

Parameters:

{"utf8"=>"?", "_method"=>"put", "authenticity_token"=>"i8C62ZtgK/PVG2Vf5AzszVqvTSX5AKQhhvDa+SY27Wk=", "commit"=>"Accept Friendship", "id"=>"28"} Toggle session dump Toggle env dump Response

Headers:

None

Naomi Freeman
Naomi Freeman
Treehouse Guest Teacher

I can't edit at the moment :/

Here's the model code:

class UserFriendship < ActiveRecord::Base belongs_to :user belongs_to :friend, class_name: 'User', foreign_key: 'friend_id'

state_machine :state, initial: :pending do
    after_transition on: :accept, do: [:send_acceptance_email, :accept_mutual_friendship!]

    state :requested 

    event :accept do
        transition any => :accepted
    end 
end

def self.request(user1, user2)
    transaction do
        friendship1 = create!(user: user1, friend: user2, state: 'pending')
        friendship2 = create!(user: user2, friend: user1, state: 'requested')

        friendship1.send_request_email
        friendship1
    end
end 

def send_request_email
    UserNotifier.friend_requested(id).deliver
end 

def send_acceptance_email
    UserNotifier.friend_request_accepted(id).deliver
end

def mutual_friendship
    self.class.where({user_id: friend_id, friend_id: user_id}).first
end

def accept_mutual_friendship
    # Grab the mutual friendship and update the state without using the state machine, so as
    # not to invoke callbacks.
    mutual_friendship.update_attribute(:state, 'accepted')
end 

end

Here's the controller:

class UserFriendshipsController < ApplicationController before_filter :authenticate_user!

def index
    @user_friendships = current_user.user_friendships.all
end

def accept
    @user_friendship = current_user.user_friendships.find(params[:id])
    if @user_friendship.accept_mutual_friendship?
        flash[:success] = "You are now friends with #{@user_friendship.user.first_name}!"
    else
        flash[:error] = "They think you're a creep."
    end 
    redirect_to user_friendships_path
end 

def new
    if params[:friend_id] #is this rails 4? 
        @friend = User.where(profile_name: params[:friend_id]).first
        #raise ActiveRecord::RecordNotFound if @friend.nil?
        @user_friendship = current_user.user_friendships.new(friend: @friend)
    else
        flash[:error] = "Oh dear ... that person seems to have disappeared. The request failed."
    end

rescue ActiveRecord::RecordNotFound
    render file: 'public/404', status: :not_found
end

def create
    if params[:user_friendship] && params[:user_friendship].has_key?(:friend_id)
        @friend = User.where(profile_name: params[:user_friendship][:friend_id]).first
        @user_friendship = UserFriendship.request(@current_user, @friend)
        if @user_friendship.new_record?
            flash[:error] = "There was a problem creating that friend request."
        else
            flash[:success] = "Friend request sent."
        end 
        redirect_to profile_path(@friend)
    else
        flash[:error] = "Oh dear ... that person seems to have disappeared. The request failed."
        redirect_to root_path
    end
end

def edit
    @user_friendship = current_user.user_friendships.find(params[:id])
    @friend = @user_friendship.friend
end

def friendships_params
  params.permit(:user_id, :friend_id, :users, :friends, :state, :first_name, :user_friendships)
end
#not sure if this params.require is necessary or if it's under user. just need somewhere for the .permit

end

1 Answer

Naomi Freeman
STAFF
Naomi Freeman
Treehouse Guest Teacher

Fixed it.

Had to put a ! at the end of the method accept_mutual_friendship

Video doesn't explain it. Shows up in "destroy friendship" video. You can just see it as you're typing other stuff.

I didn't realized you need to make methods know they're dangerous.