Tyler
Tyler

Reputation: 2386

Rails Joining together multiple tables

So I am trying to create a news feed of sorts but I am unsure as to how to make the queries.

I have a user model, a model for followed locations and a model for followed users. And then I have a model for comments. I need to grab all the comments from users that a user follows and all comments from a location that a user follows and I have to put these together.

I'm not that familiar with how to do this in sql or rails. Can anyone link me to an article or the docs where I might find how to do this?

If you need more information just comment what else I should include because I was unsure what to include in the post.

The comments model looks like this and it is polymorphic and can be posted to locations and events

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

And then there is two separate tables for following users and following locations

create_table :followed_locations do |t|
  t.integer :user_id
  t.integer :location_id

create_table :followed_users do |t|
  t.integer :user_id
  t.integer :followed_id

Upvotes: 0

Views: 100

Answers (1)

Jaime Bellmyer
Jaime Bellmyer

Reputation: 23307

Here's how the model associations would look:

class User < ActiveRecord::Base
    has_many :comments, as: :commentable
    has_many :followed_locations
    has_many :followed_users

    def followed_items
        followed_locations.map(&:location).flatten + followed_users.map(&:followed).flatten
    end
end

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

class FollowedUser < ActiveRecord::Base
    belongs_to :user
    belongs_to :followed, class_name: 'User'
end

class FollowedLocation < ActiveRecord::Base
    belongs_to :user
    belongs_to :location
end

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

The code above defines the relationships among all the models, and adds one User instance method to collect all the items (locations or users) that a given user follows. Now you can gather all the comments for users/locations that a single user is following, like so:

user.followed_items.map(&:comments).flatten

This will gather all the followed items for a user (both locations and other users), get a list of all their comments, then flatten them into a simple array. If you want to sort them, my creation for example, tack that onto the end:

user.followed_items.map(&:comments).flatten.sort_by(&:created_at)

There are ways to optimize this, but at this point you probably just want to focus on getting the concepts down.

UPDATE:

I've created a simple Rails 4 app that implements this solution, and published it on github:

https://github.com/rubycuts/so26169791

Upvotes: 1

Related Questions