1

I have an Update model which belongs to users. To show all of one user's friends' Updates, I am doing something like:

Update.where("user_id" => [array_of_friend_ids])

I know the "right" way of doing things is to create a method to create the above array. I started writing the method but it's only half-working. Currently I have this in my user model:

  def self.findfriends(id)
    @friendarray = []
    @registered_friends = Friend.where("user_id" => id)
    @registered_friends.each do |x|
      @friendarray << x.friend_id
    end 
    return @friendarray
  end 

I am doing the entire action in the view with:

<% @friendinsert = User.findfriends(current_user.id) %>
<% @friendarray  = [] %>
<% @friendarray << @friendinsert %>
<%= @friendarray.flatten! %>

Then I'm calling Update.where("user_id" => @friendarray) which works. But obviously I'm doing things in a very hacky way here. I'm a bit confused as to when Rails can "see" certain variables from models and methods in the view. What's the best way to go about inserting an array of IDs to find their Updates, since I'm not supposed to use much logic in the view itself?

Cezar
  • 55,636
  • 19
  • 86
  • 87
jenno
  • 71
  • 1
  • 2
  • 7
  • 2
    Can you please specify your model associations? I think you could solve your problem through defining associations and not through generating dirty hacky arrays :-). – Matthias Aug 10 '13 at 20:19
  • Sure... It's currently... Updates belong to a user and a User can have many updates. – jenno Aug 12 '13 at 15:40

2 Answers2

2

Mattharick is right about using associations. You should use associations for the question you mentioned in description of your question. If we come to the question at the title of your question;

let's say you have a User model.

These two methods are different:

def self.testing
  puts "I'm testing"
end

and the other one is:

def testing
  puts "I'm testing"
end

Pay attention to the self keyword. self keyword makes method a Class method. Which you can call it from your controllers or views like: User.testing.

But the one with out testing is a instance method. Which can be called like:

u = User.last
u.testing

Second one gives you possibility to use attributes of the 'instance' inside your model.

For example, you can show name of your instance in that method just like this?

def testing
  puts "Look, I'm showing this instance's name which is: #{name}"
end

These are powerful stuff.

Practise on them.

scaryguy
  • 7,720
  • 3
  • 36
  • 52
  • I do have associations... Updates belong to a user and a User can have many updates. I know how to do that bit. I'm trying to find an array of a User's friends so I can show that User's friends' updates... So the above code I have, from what you're saying, is that I should use def findfriends(id) instead of def self.findfriends(id) because the first is for instances of User and the latter is for the entire User class, correct? – jenno Aug 12 '13 at 15:39
  • I hope you're aware that there are many different association types and many different use cases. For example `has_many :through` or `polymorphic` ones. To the second part of your comment, well yes, I ment that. – scaryguy Aug 12 '13 at 22:32
1

Simple add another association to your project.

class User < ActiveRecord::Base

  has_many :friendship
  has_many :friends, :through => :friendship, :class_name => User, :foreign_key => :friend_id

  has_many :friendship
  has_many :users, :through => :friendship

end

class Friendship < ActiveRecord::Base

  belongs_to :user
  belongs_to :friend, :class_name => User

end

I don't know if my synrax is correct, please try out.

Friendship has the attributes user_id and friend_id.

After that you should be able to do something like following to get the updates of a friend:

User.last.friends.last.updates

You can work with normal active record queries instead of hacky arrays..

Matthias
  • 4,355
  • 2
  • 25
  • 34
  • Thanks for your response. I've always been a little confused with the has_many through associations. My problem is I don't know what models need what attributes. For example I know my user model needs: id, name, email. In the beginning my Friends model had: id, user_id, and friend_id. So what you're suggesting is to create a Friendship model instead with these attributes (id, userid, friendid)? Then what would the attributes be for the Friend model? It can't be the same thing..? – jenno Aug 14 '13 at 21:35
  • You have a special case. Normally a has_many through association is between two models, with a third model in between. In your case you create the association only within the user model. An user can have multiple friends. But a friend is also an user. An user has a friendship to an other user. That's the reason why I called the model friendship. The friendship model is the model between an user and another user. Friendship should simple have the attributes user_id and friend_id. – Matthias Aug 14 '13 at 23:04
  • Thanks for clarifying! I understand that I'm supposed to add your code in the original answer to my User model. In that code I see 3 models: user, friends, and friendships. In your code, is it correct to say that the Friend model is just another name for User, because we need to give it a different name from User? – jenno Aug 15 '13 at 16:11
  • Exactly, you only have two models, but three names. Friend is just a name to associate one user with another one within one class. Rails knows through the keyword :class_name => User, that a "friend" also uses the User class. – Matthias Aug 15 '13 at 16:17