1

I updated the question because I combined following locations and users into one polymorphic model.

So I am trying to make a news feed for comments in my app.

I have a user model, a model for following locations and users. And then I have a model for comments.

How do I grab the comments from users that a user follows and comments from a location that a user follows and put these together?

I need this to be paginated as well as sorted by the created_at time stamp ( showing newest first).

Heres what my migrations look like

create_table :comments do |t|
  t.text :text
  t.integer :user_id
  t.integer :commentable_id
  t.string :commentable_type

create_table :follows do |t|
  t.integer :user_id
  t.integer :followable_id
  t.string :followable_type

And this is what my models look like

class User < ActiveRecord::Base
    has_many :comments, as: :commentable
end

class Comment < ActiveRecord::Base
    belongs_to :commentable, polymorphic: true
end

update: I found something called a CASE statement in sql (like an if statement) How do I perform an IF...THEN in an SQL SELECT?

I am still unsure of how to write this query but I think the CASE statement may help.

Community
  • 1
  • 1
Tyler
  • 2,346
  • 6
  • 33
  • 59
  • What is the question? – Brennan Oct 14 '14 at 20:09
  • I edited the question sorry for not being clear – Tyler Oct 14 '14 at 20:21
  • Can a user comment on anything besides a location? If not, you do not need a polymorphic relationship. You should have a polymorphic relationship for follows though, that way you'd have a model like: `class Follow < ActiveRecord::Base belongs_to :user belongs_to :followable, polymorphic: true` – saskcan Oct 14 '14 at 20:50
  • Yeh they can comment on other things thats why its polymorphic. I didn't think of having the following polymorphic. If I do that what would the query look like then? I imagine its a lot simpler this way too. Thanks! – Tyler Oct 14 '14 at 21:02
  • Post all your models and your schema.rb please. – Niels B. Oct 18 '14 at 21:15

1 Answers1

0

If I'm gathering your question correctly you might see something like this for a model:

class User < ActiveRecord::Base

  has_many :comments, as: :commentable, dependent: :nullify

  has_many :follows, dependent: :destroy
  has_many :followed_users, class_name: 'Follow', conditions: {followable_type: 'User'}
  has_many :followed_locations, class_name: 'Follow', conditions: {followable_type: 'Location'}

  has_many :followers, as: :followable, dependent: :destroy

end

And in your controller you might see something like this:

# See all comments made by those you follow (and yourself)
# See all comments made on locations you follow
# See all comments made on users you follow
@comments = Comment.where(
  'user_id in (:followed_user_ids) or (commentable_type = 'Location' and commentable_id in (:followed_location_ids)) or (commentable_type = 'User' and commentable_id in (:followed_user_ids))',
  { 
    followed_user_ids: current_user.followed_users.pluck(:user_id) | [current_user.id], 
    followed_location_ids: current_user.followed_locations.pluck(:location_id)
  }
).paginate(page: params[:page]).order(created_at: :desc)

As this gets more complex, and it will get much more complex, look into scopes and merging. Probably pulling this method out into a search class somewhere.

James Daniels
  • 6,883
  • 4
  • 24
  • 28