Saff
Saff

Reputation: 563

Rails activity feed from a polymorphic following

I'm tracking the following tables:

Story (id, user_id, content)
Vote  (id, user_id, story_id)
Flag  (id, user_id, story_id)
etc..

with an activity table:

Activity (id, user_id,action, trackable_id, trackable_type)

The relationship table:

Relationship (id, follower_id, followed_id)

I'm currently getting the activities from users a user is following like this:

def get_activity_from_followers(current_user)
     followed_user_ids = "SELECT followed_id FROM relationships
                         WHERE follower_id = :user_id"
    where("user_id IN (#{followed_user_ids})",
          user_id: user.id)
end

My question is, how do i get the activities where the the trackable table(e.g. story,vote,flag) belongs to you.
So right now i'm getting things like:

  1. "someone you are following" posted a story
  2. "someone you are following" voted a story


i want to also get things like:

  1. "someone you are not following" voted your story
  2. "someone you are not following" flagged your story

How do I go about this? Thanks.

Upvotes: 4

Views: 531

Answers (3)

Sergey Moiseev
Sergey Moiseev

Reputation: 2963

What about making Activity STI class?

class Story < ActiveRecord::Base
  belongs_to :user
end

class Activity < ActiveRecord::Base
  belongs_to :story
  belongs_to :user
end

class Vote < Activity
  def to_partial_path
    'users/vote'
  end
end

class Flag < Activity
  def to_partial_path
    'users/flag'
  end
end

You can store all user actions in same table and get it from there with:

Activity.where(user_id: uid).all 

and you get as return array of all user actions with correct typing for every action, that allow you to implement polymorphic logic for different types of actions (as to partial path in my example, that allows you to write something like:

render Activity.where(user_id: uid).all  

Upvotes: 0

Sandip Ransing
Sandip Ransing

Reputation: 7733

I suggest you have following class definitions and associations:

# User 
class User  :trackable
end

# Flag  (id, user_id, story_id)
class Flag  :trackable
end

# with an activity table:
# Activity (id, user_id,action, trackable_id, trackable_type)
class Activity  true
end

# The relationship table:
# Relationship (id, follower_id, following_id)
class Relationship  "User"
  belongs_to :following, :class_name => "User"
end

Now, Lets find activities of the users to whom you follow:


# List activities of my followings
Activity.where(:user_id => current_user.followings)

Listing my activities

current_user.activities

Upvotes: 1

IBueno
IBueno

Reputation: 83

To solve this, I'd search into Activity using votes and flags id's instead of user id's. Something like this:

def get_votes(current_user)
 stories = current_user.stories
 votes = Votes.where(story_id: stories.map {|s| s.id})
 activity = Activity.where(action: 'vote', trackable_id: votes.map{|v| v.id})
end

I madre some assumptions. First that you can call user.stories, and then that in Activity model 'action' can be vote or flag and that trackable_id relates to Vote and Flag id. If that's not correct, you can get the general idea anyways.

Hope it helps

Upvotes: 0

Related Questions