0

I am making a Twitter clone using rails 4 just for practice. When a user is logged in, on the timeline I only want to display tweets of the people they follow (friends) and their own tweets in DESC order. I'm using tweets#index as my timeline. Currently I am displaying all tweets in the database to the user:

def index
  @tweets = Tweet.all.order("created_at DESC")
end

I added an instance variable called @user_friendships that contains the current logged in users friends, witch I can then iterate through and access their tweets. Here is what it now looks like:

def index
  @user_friendships = current_user.user_friendships.all
  @tweets = Tweet.all.order("created_at DESC")
end

I don't want to loop through user_friendships and grab it's friend and then tweets in the view as well as loop through the current_users tweets.

In the controller, I want to have one instance variable that contains the tweets of both the current_user and each friends tweets in user_friendships...so in the View I only have to iterate through the new array.

Model Code

### User.rb

has_many :tweets

has_many :user_friendships
has_many :friends, through: :user_friendships

acts_as_voter

def to_param
  username
end

### user_friendship.rb

belongs_to :user
belongs_to :friend, class_name: 'User', foreign_key: 'friend_id'


### tweet.rb

belongs_to :user

3 Answers 3

1
def index
   @tweets = current_user.related_tweets.sort_by{|t| t.created_at}.reverse!
end

in model User

class User < ActiveRecord::Base
   # ...
   def related_tweets
      friends_tweets = friends.map{|f| f.tweets}
      return (tweets.to_a + friends_tweets).flatten
   end
   # ...
end

or other solution if you dont want to work with arrays

def index
   @tweets = Tweet.for_user(current_user).order(cretead_at: :desc)
end

in model Tweet

class Tweet < ActiveRecord::Base
   # ...
   def self.for_user user
      me_and_friends = [user.id] + user.friends.map(&:id)      
      where(:user_id => me_and_friends)
   end
   # ...
end
Sign up to request clarification or add additional context in comments.

2 Comments

One more question, if I wanted to have them ordered by created_at in DESC order, would I do that in the model? Thanks again
It is better to order in controller.That way you don't pollute your method in model, and you can use it at more places and every time order by 'created_at' or any other attribute.
1

You didn't show the relations you have between tweets and users, but I assume you've got user has many tweets. Then, you can do something like this:

@tweets = Tweet.where(user_id: [current_user.id].concat(current_user.user_friendships.all.map(&:id)))

2 Comments

hmm, this is still only returning my tweets. Would it help if I added the code for the models? I'll add them to original post.
sorry, I was away, but now I see you've already got answered:)
0

You can do something like this:

def index
  @tweet_wall = Tweet.all.where(user_id: current_user.id).where(relationship between user and friend)
end

Second condition would depend on your model.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.