Aleks K
Aleks K

Reputation: 5

Rails: how to display all pending friend requests?

I'm working on my first Rails project and I have a small problem. I'd really appreciate any help. I want to display all pending friend requests for a current user using each iterator. My controller:

class FriendRequestsController < ApplicationController
before_action :set_friend_request, except: [:index, :new, :create]

def index
  @incoming = FriendRequest.where(friend: current_user)
  @outgoing = current_user.friend_requests
end

def new
  @friend_request = FriendRequest.new
end

def create
  friend = User.find(params[:friend_id])
  @friend_request = current_user.friend_requests.new(friend: friend)
  if @friend_request.save
    redirect_back(fallback_location: root_path), status: :created, location: @friend_request
  else
    render json: @friend_request.errors, status: :unprocessable_entity
  end
end

When I try something like a code below, it kinda works, the conditional statement works as it should, but I know it's a terrible way to make it work, so I'd like to use @incoming since it's defined.

<% if FriendRequest.where(friend: current_user).present? %>
   <% ?.each do |request| %>
       <li><%= ? %></li>
   <% end %>
<% else %>
    You don't have any friend requests
<% end %>

But when I try something like:

<% if @incoming.present? %>

The conditional statement doesn't work properly and there's 'You don't have any friend requests', even though the current user has a pending friend request. I don't exactly get how everything works in RoR yet, so I'd be thankful for an explanation.

Upvotes: 0

Views: 949

Answers (2)

max
max

Reputation: 102212

Lets start by creating a specific association for incoming friend requests.

class User < ActiveRecord::Base
  # ...
  has_many :incoming_friend_requests,
    class_name: 'FriendRequest',
    source: :friend
end

Since Rails cannot derive the proper columns from the name of the association we specify the class_name. source tells Rails what association on FriendRequest is the inverse.

This is extremely important when you start to look at eager loading and performance.

For example it lets you do:

@user = User.joins(:friend_requests, :incoming_friend_requests)
            .find(params[:id])

So lets use the new relation:

def index
  @incoming = current_user.incoming_friend_requests
  @outgoing = current_user.friend_requests
end

To test if there are any items in a scope or collection use .any?. .any? is pretty smart in that it won't issue a query if the association is already loaded.

<% if @incoming.any? %>
  <ul>
  <% @incoming.each do |fr| %>
    <li><%= fr.name %></li>
  <% end %>
  </ul>
<% else %>
  <p>You don't have any friend requests</p>
<% end %>

Upvotes: 0

ilan berci
ilan berci

Reputation: 3881

<% if (frs = FriendRequest.where(friend: current_user)).present? %>
   <% frs.each do |fr| %>
       <li><%= fr.name %></li>
   <% end %>
<% else %>
    You don't have any friend requests
<% end %>

Upvotes: 1

Related Questions