← Back to Upcase

Find all the posts by all the groups

(Charlieanna) #1

I need to find all the groups created by the current user and then find all the posts combined present in these groups and then display them in a timeline in a reverse order. Below is the code for only the post of a single group. How could I do this for all the groups and make sure it is database optimised as well.

@group = current_user.following_groups.first
@posts = @group.alerts + @group.notes
@posts = @posts.sort_by(&:created_at).reverse

I thought of

groups = current_user.groups
total_posts = []
groups.each do |group| 
  posts = group.alerts + group.notes
  total_posts <<  posts
@posts = total_posts
@posts = total_posts.flatten
@posts = @posts.sort_by(&:created_at).reverse

Do I need to include in such a case?

I came up with this using the bullet gem but I dont think I understood what includes did here.

@group = Group.new(user: current_user)
groups = current_user.groups
total_posts = []
groups.each do |group| 
  posts = group.alerts.includes(:group) + group.notes.includes(:group)
  total_posts <<  posts
@posts = total_posts.flatten
@posts = @posts.sort_by(&:created_at).reverse

(Matthew Sumner) #2

includes allows you to eager load associated records.

groups = current_user.groups.includes(:alerts, :notes)

This will return all the groups and the alerts and notes for each group. This means you can then grab all the alerts and notes with something like:

alerts = groups.map { |group| group.alerts }.flatten
notes = groups.map { |group| group.notes }.flatten

(Charlieanna) #3

But any idea how would I combine the alerts and posts and then show them in a reverse order of created at. ? Is there any method better than this?

(Matthew Sumner) #4

So then you could do what you were doing before i.e. @posts = (alerts + notes).sort_by(&:created_at).reverse.

With your code you will grab all the groups and then make two requests for each group to get their alerts and notes. By using includes you make one database request instead of many. The sorting and reverse shouldn’t be too expensive.

I don’t know of a way through activerecord to get all the data you want already sorted. There may be a way using Arel for which there is a railscast.

(Matthew Sumner) #5

There’s a great post on the robots blog about using polymorphism to easily find related records. Might be worth reading for this problem.

(Charlieanna) #6

Thanks @DeviousDuck. Even I had thought about having a class called Post which either could be a note or an alert and have polymorphism and use Group has_many posts, something like that, when I got stuck and posted this problem here.

(Charlieanna) #7

@DeviousDuck This is what I did.

Class User 
has_many notes through :groups
has_many alerts through :groups 

which gives me

 @posts = current_user.alerts + current_user.notes. 

But now I am trying to figure out a way to do current_user.posts which will then straight return me the combination of the alerts and notes.

I thought

User has_many :posts

but then have a polymorphic relation between the post and the alerts/notes because a post could be either an alert or a note.

Or should I instead have a method on the User def post which then returns me self.alerts + self.notes?

But in this case then I would to create a corresponding post for any previous alerts, notes created. I read that thoughtbot article. But not much made sense to me.