Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Here I retrieve a collection of causes from the database. Along with the information from each cause, I want to send the number of users in each cause. This way works, but if experience has told me anything there is probably a much more efficient method to do this. How can I improve this?

  def index
    @causes = Cause.near([params[:lat], params[:lng]],10)
    @causes.each do |i|
      i['count'] = i.users.count
    end
    respond_to do |format|
      format.json { render json: {:success=> 1, :data_type => 'cause',:results => @causes} }
    end
  end
share|improve this question
add comment

1 Answer 1

up vote 5 down vote accepted

You can perform an inner-join on the users table and then group by the causes.id.

@causes = Cause
  .near([params[:lat], params[:lng]], 10)
  .joins('users')
  .group('causes.id')
  .select('causes.*, count(users) as count')
share|improve this answer
    
Thanks for the answer! I'm not trying to be a smart ass, but is this better or just different? Can you explain why? Thanks –  Emin Israfil Nov 28 '12 at 16:06
2  
This is more efficient because the number of queries to database is reduced to one. It also places the work onto the database which is optimized for this task through caching and indexing. –  peterpan Nov 28 '12 at 16:22
    
Thanks for getting back to me. It doesn't seem to work. More info posted above :) –  Emin Israfil Nov 28 '12 at 18:31
    
@user15872 What does Cause.select('causes.id,count(users) as people').joins(:users).group('causes.id').first.people output? –  peterpan Nov 29 '12 at 0:44
1  
You say its not in the hash but AR is not returning a hash it is returning a ActiveRecord::Relation. What it is printing to the screen is not necessarily what will be in the json. What does this show? Cause.select('causes.id,count(users) as people').joins(:users).group('causes.id').as_json –  peterpan Nov 29 '12 at 16:52
show 7 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.