Friendship System Rails 3.0

I am trying to develop a friendship system like facebook. I have follow
for guidance the two following sources

How to Implement a Friendship Model in Rails 3 for a Social Networking
Application?
Railsspace book chapter 14, which can only be downloaded i believed
I am a bit confused on the way railsspace has been building there
relationship. What i am trying to do his to show in a views my
pending_request, accepted_request and declined_request. The books seem
to suggest the following relationship

FriendshipModel

class Friendship < ActiveRecord::Base
belongs_to :customer
belongs_to :friend, :class_name => ‘Customer’, :foreign_key =>
‘friend_id’
CustomerModel

class Customer < ActiveRecord::Base
#RELATIONSHIP
has_many :friendships
has_many :friends, :through => :friendships,
:conditions => “status = ‘accepted’”
has_many :requested_friends,
:through => :friendships,
:source => :friend,
:conditions => “status = ‘requested’”
has_many :pending_friends,
:through => :friendships,
:source => :friend,
:conditions => “status = ‘pending’”
The issues i am having his how can i access friends who are pendings,
friends who are requested. I have the following view in my index
(friendship/index)

Request

<% @customer.friends.each do |friend| %> <% end %>
<%= link_to friend.first_name, '#' %>
But i get the following errors

NoMethodError in Friends#index

Showing /app/views/friends/index.html.erb where line #15 raised:

undefined method `friends’ for #Array:0xb6144040
Extracted source (around line #15):

12:
13:

Request


14:
15: <% @customer.friends.each do |friend| %>
16:
17:
18:
Mind you, my model is called friendship, my controller his called
friends ( not the best name but its more for practise learning I did)

Here the model

Table name: friendships

id :integer not null, primary key

customer_id :integer

friend_id :integer

created_at :datetime not null

updated_at :datetime not null

approved :string(255)

Customer Schema

Table name: customers

id :integer not null, primary key

email :string(255) default(""), not null

created_at :datetime not null

updated_at :datetime not null

first_name :string(255)

middle_name :string(255)

last_name :string(255)

isadmin :boolean default(FALSE)

isMod :boolean default(FALSE)

<%= link_to friend.first_name, ‘#’ %>

undefined method `friends’ for #Array:0xb6144040

You didn’t show us the controller code that defines @customer but I’ll
bet you used something returned an array when you wanted a single
object.

Also, be sure to note that Rails 3.1 finders return ARels (active record
relation objects) which are array-like, pre-Rails 3.1 you get an actual
array. So you get some funny business when upgrading from pre-Rails 3.1
to Rails 3.1 or higher when doing stuff like this, because ARels can
behave like Arrays but aren’t actually arrays.

Jason Fb wrote in post #1072568:

undefined method `friends’ for #Array:0xb6144040

You didn’t show us the controller code that defines @customer but I’ll
bet you used something returned an array when you wanted a single
object.

Interesting about the Arel thing but here the controller

class FriendsController < ApplicationController

before_filter :setup_friends

def index
@customer = Customer.all
end

#Send a friend request
def create
Friends.request(@customer, @friend)
end

private
def setup_friends
@customer = current_customer
@friend = Customer.find_by_id(params[:id])
end
end

You seem to have defined @customer twice, once in the setup_friends
method which is run first as a before_filter hook, and then again in the
index method. the one in the index method returns an array, since you
asked for @customer.all

On 17 August 2012 16:36, Jean-Sbastien D. [email protected] wrote:


Sorry for the late reply, after notice I did change many thing. ( redid
from scracth)

So here an updated code
[massive snip]

I doubt whether anyone has time to wade through all that code in order
to understand your problem (though I may be proved wrong). You must
try to ask a more specific question.

Colin

Jason Fb wrote in post #1072573:

You seem to have defined @customer twice, once in the setup_friends
method which is run first as a before_filter hook, and then again in the
index method. the one in the index method returns an array, since you
asked for @customer.all

Sorry for the late reply, after notice I did change many thing. ( redid
from scracth)

So here an updated code

Friendship Model ( and rename table to friendship )
class Friendship < ActiveRecord::Base

belongs_to :customer
belongs_to :friend, :class_name => ‘Customer’, :foreign_key =>
‘friend_id’

validates_presence_of :customer_id, :friend_id
attr_accessible :approved, :customer_id, :friend_id

#Method

Return true if the customers are (possibly pending) friends.

def self.exists?(customer, friend)
not find_by_customer_id_and_friend_id(customer, friend).nil?
end

Record a pending friend request.

def self.request(customer, friend)
unless customer == friend or Friendship.exists?(customer, friend)
transaction do
create(:customer => customer, :friend => friend, :status => ‘pending’)
create(:customer => friend, :friend => customer, :status =>
‘requested’)
end
end
end

Accept a friend request.

def self.accept(customer, friend)
transaction do
accepted_at = Time.now
accept_one_side(customer, friend, accepted_at)
accept_one_side(friend, customer, accepted_at)
end
end

Delete a friendship or cancel a pending request.

def self.breakup(customer, friend)
transaction do
destroy(find_by_customer_id_and_friend_id(customer, friend))
destroy(find_by_customer_id_and_friend_id(friend, customer))
end
end

private

Update the db with one side of an accepted friendship request.

def self.accept_one_side(customer, friend, accepted_at)
request = find_by_customer_id_and_friend_id(customer, friend)
request.status = ‘accepted’
request.accepted_at = accepted_at
request.save!
end
end

Customer Model
class Customer < ActiveRecord::Base

#RELATIONSHIP

has_many :friendships
has_many :friends, :through => :friendships,
:conditions => “status = ‘accepted’”
has_many :requested_friends,
:through => :friendships,
:source => :friend,
:conditions => “status = ‘requested’”
has_many :pending_friends,
:through => :friendships,
:source => :friend,
:conditions => “status = ‘pending’”
end

Controller Friendship
class FriendshipsController < ApplicationController

before_filter :setup_friends

def accept
if @customer.requested_friends.include?(@friend)
Friendship.accept(@customer, @friend)
flash[:notice] = “Friendship Accepted”
else
flash[:notice] = “No Friendship request”
end
redirect_to root_url
end

def decline
if @customer.requested_friends.include?(@friend)
Friendship.breakup(@customer, @friend)
flash[:notice] = “Friendship Declined”
else
flash[:notice] = “No Friendship request”
end
redirect_to root_url
end

def cancel
if @customer.pending_friends.include?(@friend)
Friendship.breakup(@customer, @friend)
flash[:notice] = “Friendship Canceled”
elserequested
flash[:notice] = “No Friendship request”
end
redirect_to root_url
end

def delete
if @customer.friends.include?(@friend)
Friendship.breakup(@customer, @friend)
flash[:notice] = “Friendship Deleted”
else
flash[:notice] = “No Friendship request”
end
redirect_to root_url
end

def index
@customers = Customer.all
end

#Send a friendship request
def create
Friendships.request(@customer, @friend)
end

private
def setup_friends
@customer = current_customer
@friend = Customer.find_by_id(params[:id])
end
end

Now here the issue i seem to not really understand but is to manager the
relationship and here my code atm.
This is in index.html.erb from friendship and list everything,

Friends

<% @customer.friends.each do |friend| %>
<%= link_to friend.incomplete_name, ‘#’ %>

<% end %>

Request

<% @customer.requested_friends.each do |rf| %>
<%= link_to rf.incomplete_name, ‘#’ %>

<% end %>

Pendings

<% @customer.pending_friends.each do |pf| %>
<%= link_to pf.incomplete_name, ‘#’ %>

<% end %>

Users

<% @customers.each do |customer| %> <% if current_customer != customer %>
<%= friendship_status(current_customer, customer) %>
<% unless Friendship.exists?(current_customer, customer) %> <%= link_to "Request friendship with #{customer.first_name}", { :controller => "friendships", :action => "create", :id => customer.id }, :confirm => "Send friend request to #{customer.incomplete_name}?" %> <% end %> <% end %> <% end %>

In railspace they use an email link to accept, but i don’t want to send
an email and not sure how to refresh page with the proper information.

Thanks in advance

Colin L. wrote in post #1072687:

I doubt whether anyone has time to wade through all that code in order
to understand your problem (though I may be proved wrong). You must
try to ask a more specific question.

Colin

I understand and didn’t want at first because its a lot of code, but
just wanted to make sure it was understood properly ( language barrier
sometime). Anyway

I am trying to create a relationship among the users, in my controller I
have 2 function create and accept.

When clicking in my view file I have link_to which create the
friendship.
<%= link_to “Request friendship with #{customer.first_name}”,
{ :controller => “friendships”, :action => “create”,
:id => customer.id },
:confirm =>
“Send friend request to #{customer.incomplete_name}?” %>

However I do not see when refreshing that a friendship has really been
created. In what ever states

I believe the issue is here

has_many :requested_friends,
:through => :friendships,
:source => :friend,
:conditions => “status = ‘requested’”

I am just suppose to say @customer.requested_friends and this would
allow me iterate through each of them??

Thanks again

On 17 August 2012 17:01, Jean-Sbastien D. [email protected] wrote:

sometime). Anyway
“Send friend request to #{customer.incomplete_name}?” %>
Are you using a GET request to create records in the database? This
is generally considered a bad idea.

However I do not see when refreshing that a friendship has really been
created. In what ever states

So has it been created or not? Look directly at the database if
necessary, to check. If not then get that working first before
worrying about any views. Run
rails console
then you can do things like
Friendship.all
and it will show them all. In addition you can run any ruby code to
interrogate the db in the same way as you do in the app (using find
and so on).

allow me iterate through each of them??
Yes, but check first as I said above that you are creating the
friendships correctly first. I am sure I have pointed you to the
Rails Guide on debugging already, but if not then have a look at it.

Colin

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs