简体   繁体   中英

Performance improvement for Rails associated model aggregation

I have a Model called Person and Person has multiple posts. When I want to query post count for each person it takes a long time to process since it needs to iterate over each person and query each posts to get the aggregation.

class Person < ActiveRecord::Base
has_many :posts
end

Output (JSON):

Person1
  PostsType1Count: 15
  PostsType2Count: 45
Person2
  PostsType3Count: 33
.
.
.

I want to calculate all the post count for each Person in a optimum way. What would be the best solution?

Here's one way to do this, if you have a small and pre-defined set of Types

class Person < ActiveRecord::Base
  has_many :type_1_posts, :class_name => 'Post', :conditions => 'post_type = 1'
  has_many :type_2_posts, :class_name => 'Post', :conditions => 'post_type = 2'
  has_many :type_3_posts, :class_name => 'Post', :conditions => 'post_type = 3'
end

Then you can write code that looks like this to get all the data:

@all_people = Person.includes(:type_1_posts, :type_2_posts, :type_3_posts).all

The eager loading of the posts allows the count of each type of post to be available, as well as all the posts of each type.

If you need extra performance for this code, because you perform this query a lot, then you can look into using the Rails counter cache mechanism to keep track of the counts of each type on the Person object.

The beauty of Rails here is that your main display code doesn't need to change during this process of making the code faster for reading (adding a counter cache makes adding/deleting posts slower, so you may not want it in all cases).

  1. Write initial code
  2. Use eager loading to make it faster
  3. Use counter cache to make it even faster

Try this May it will work for you

    #In Controller
    @persons = Person.all
    #In View
    @persons.each do |person|
         person.posts.count # It will gives all posts count
         person.posts.collect{|x| true if x.type==1 }.compact.count #If you want to get the post counts based on type
    end

Suppose if you want to get any mehods just check in console or debug is person.methods.sort it will give all methods.
try in rails console person.posts.methods also it will give types also then check counts based on type. because i dont know which fields in posts model. so check it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM