Rails has_many association count child rows

前端 未结 5 551
误落风尘
误落风尘 2020-12-13 14:07

What is the \"rails way\" to efficiently grab all rows of a parent table along with a count of the number of children each row has?

I don\'t want to use counte

相关标签:
5条回答
  • 2020-12-13 14:17

    I made this work this way:

    def show
      section = Section.find(params[:id])
      students = Student.where( :section_id => section.id ).count
      render json: {status: 'SUCCESS', section: students},status: :ok
    end
    

    In this I had 2 models Section and Student. So I have to count the number of students who matches a particular id of section.

    0 讨论(0)
  • 2020-12-13 14:27

    Rails 3 Version

    For Rails 3, you'd be looking at something like this:

    Article.select( "articles.*, count(comments.id) AS comments_count" )
      .joins( "LEFT OUTER JOIN comments ON comments.article_id = articles.id" )
      .group( "articles.id" )
    

    Thanks to Gdeglin for the Rails 2 version.

    0 讨论(0)
  • 2020-12-13 14:30

    This activerecord call should do what you want:

    Article.find(:all, :select => 'articles.*, count(posts.id) as post_count',
                 :joins => 'left outer join posts on posts.article_id = articles.id',
                 :group => 'articles.id'
                )
    

    This will return a list of article objects, each of which has the method post_count on it that contains the number of posts on the article as a string.

    The method executes sql similar to the following:

    SELECT articles.*, count(posts.id) AS post_count
    FROM `articles`
    LEFT OUTER JOIN posts ON posts.article_id = articles.id
    GROUP BY articles.id
    

    If you're curious, this is a sample of the MySQL results you might see from running such a query:

    +----+----------------+------------+
    | id | text           | post_count |
    +----+----------------+------------+
    |  1 | TEXT TEXT TEXT |          1 |
    |  2 | TEXT TEXT TEXT |          3 |
    |  3 | TEXT TEXT TEXT |          0 |
    +----+----------------+------------+
    
    0 讨论(0)
  • 2020-12-13 14:32

    From a SQL perspective, this looks trivial - Just write up a new query.

    From a Rails perspective, The values you mention are computed values. So if you use find_by_sql, the Model class would not know about the computed fields and hence would return the computed values as strings even if you manage to translate the query into Rails speak. See linked question below.
    The general drift (from the responses I got to that question) was to have a separate class be responsible for the rollup / computing the desired values.

    How to get rails to return SUM(columnName) attributes with right datatype instead of a string?

    0 讨论(0)
  • 2020-12-13 14:36

    A simple way that I used to solve this problem was

    In my model I did:

    class Article < ActiveRecord::Base
      has_many :posts
    
      def count_posts
        Post.where(:article_id => self.id).count
      end
    end
    

    Now, you can use for example:

    Articles.first.count_posts
    

    Im not sure if it can be more efficient way, But its a solution and in my opinion more elegant than the others.

    0 讨论(0)
提交回复
热议问题