Topic: has_many_friends: limiting results

OK guys, I've been using has_many_friends which is a great plugin, but I've hit a snag.

On my user profile pages I just want to display the first 8 friends that a user has. You don't seem to be able to do this out of the box with has_many_friends. Does anyone have any suggestions?

I'm currently pulling the users friends using:

@friends = @user.friends

so preferably something I can add to the User model, so I don't have to hack away at the rest of the site or someway I can edit the plugin.

Also does anyone have any experience getting has_many_friends to play nicely with paginating_find?

Thanks guys

Re: has_many_friends: limiting results

I've never ever used has_many_friends. But with a normal find, you do this:

SomeModel.find(:all, :limit => 8)

Probably something similar for has_many_friends.

Re: has_many_friends: limiting results

Thanks for the reply.

I've already tried what you suggested and got the following error:

"wrong number of arguments (2 for 1)"

When I try:

@friends = @user.friends.find(:all, :limit => 8)

Re: has_many_friends: limiting results

After looking at the has_many_friends code, I've managed top limit the friends loaded. But the problem is it's loading the actual records from the friends table rather than the user models which is what I need.

@friends = Friendship.find :all,
  :conditions => ["(user_id = ? OR friend_id = ?)", @current_user.id, @current_user.id],
  :limit => 8

Which gives me:

---
- !ruby/object:Friendship
  attributes:
    accepted_at: 2007-09-11 15:00:31
    id: "1"
    user_id: "2"
    created_at: 2007-09-11 15:00:31
    friend_id: "1"
- !ruby/object:Friendship
  attributes:
    accepted_at: 2007-09-11 15:00:31
    id: "2"
    user_id: "1"
    created_at: 2007-09-11 15:00:31
    friend_id: "2"
- !ruby/object:Friendship
  attributes:
    accepted_at: 2007-09-11 15:00:31
    id: "3"
    user_id: "1"
    created_at: 2007-09-11 15:00:31
    friend_id: "3"

etc.

How can I make it so it returns the users instead of the friend records?

Re: has_many_friends: limiting results

First off, the code you get an error with should work normally... no idea whats wrong there.

Anyhow, on your latest question:
1) include
2) trim the results.

friendships = Friendship.find :all,
  :conditions => ["(user_id = ? OR friend_id = ?)", @current_user.id, @current_user.id],
:limit => 8, :include => [:user,:friend]

@friends = friendships.map {|f| [f.user,f.friend]}.flatten.uniq.delete_if {|u| u = @user }
# get user & friend from friendship, put them in a nested array, flatten it,
# remove duplicates and finally remove all user objects that equal the current user ...
#

Last edited by Duplex (2007-09-24 08:26:35)

Re: has_many_friends: limiting results

Hi Duplex,

Thanks for the reply.

I edited my controller like you said (it's in a controller for now til I get it working then I'll move it to the model). It now looks like this:

  def user
      @user_id = params[:id]
      @user = User.find_by_url_slug(@user_id)
      friendships = Friendship.find :all,
          :conditions => ["(user_id = ? OR friend_id = ?)", @current_user.id, @current_user.id],
          :limit => 8,
          :include => [:user, :friend]
         
      @friends = friendships.map {|f| [f.user, f.friend]}.flatten.uniq.delete_if {|u| u = @current_user }
  end

But I get the following error:

Association named 'user' was not found; perhaps you misspelled it?

Re: has_many_friends: limiting results

could you post your models so we can see your associations?

Re: has_many_friends: limiting results

class User < ActiveRecord::Base
    acts_as_commentable
    acts_as_viewable
    acts_as_slugable :source_column => :login
   
    has_many :images
    has_many :interests
    has_many :messages
    belongs_to :sex
    belongs_to :status
    has_one :avatar
    has_one :banner
    has_many_friends
   
    validates_length_of :login, :within => 3..40
    validates_length_of :password, :within => 5..40, :if => :new_password?
    validates_presence_of :login, :email, :salt
    validates_presence_of :password, :password_confirmation, :if => :new_password?
    validates_acceptance_of :tos, :over_18
    validates_uniqueness_of :login, :email
    validates_confirmation_of :password
    validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :message => "Invalid email" 

    [SNIP]
end

Re: has_many_friends: limiting results

Hi Kjimn,

I got it at last, have been struggling with this for a few days, its so simple:

write these queries in your controller method instead of @friends = @user.friends:

   @friends = @user.friends_for_me.find(:all,
:order => "accepted_at desc",
:limit => "3") + @user.friends_by_me.find(:all,
:order => "accepted_at desc",
:limit => "3")

thats it, it works...

Have fun now!

Re: has_many_friends: limiting results

Doh.

Seems so simple once you put it like that haha.

I'll give it a whirl and let you know how I go on.

Thanks a lot smile