Matthew Higgins
Matthew Higgins

Reputation: 608

Rails .count and .each give a different number of results

I'm working with a simple rails app locally for my own learning.

In my view, I have the following code;

  Reviews (<%= @reviews.count %>)
  <% if @reviews.any? %>
      <% @reviews.each do |review| %>
          This is one review <br />
      <% end %>
  <% end %>

Despite this seeming quite simple, the output is as follows;

Reviews (2)

This is one review

This is one review

This is one review

This seems to contradict itself on what should be a very simple pair of operations on the same array.

For reference, the array is built in the controller, using the following code;

class PlacesController < ApplicationController
  def show
    @place = Place.find(params[:id])
    @reviews = @place.reviews
    @title = @place.name
  end
end

What might be the problem?

Upvotes: 0

Views: 106

Answers (3)

Matthew Higgins
Matthew Higgins

Reputation: 608

I don't like answering my own question, but I think it's important to explain what I found out incase anyone else ends up in the same place.

As Vitalyp suggested, replacing @reviews = @place.reviews.uniq with @reviews = @place.reviews.uniq produced the correct number of rows, but I was struggling to work out why, when opening the table clearly showed there were only two records.

It turned out there was another model, one I had previously tried using, to create a many-to-many association, which was confusing matters. It would appear that as I hadn't fully removed it after deciding not to use it, and when I completely destroyed the model, it's tables and anything that referenced it, things went back to normal.

It would appear that review 1 was associated with the place twice, once directly and once via the old many-to-many table, so it appeared twice.

It doesn't make a huge amount of sense when I had deleted the has_many:, but I guess it is a peculiarity of how Rails works.

Upvotes: 1

Vitalyp
Vitalyp

Reputation: 1089

Seems to fix it. Any idea why? – Matthew Higgins

SQL Inner joins took a place here :) They produces a duplicate entities. You can ensure, by modifying your controller:

 def show
   @place = Place.find(params[:id])
   sql_query = @place.reviews.to_sql
   render text: sql_query       
 end

You'll see sql query in browser. Then execute this query in you database manager, and you'll see the duplicated results set.

Upvotes: 1

Vitalyp
Vitalyp

Reputation: 1089

I would venture to answer: try to change code inside controller to:

@reviews = @place.reviews.uniq

And check the result.

Upvotes: 2

Related Questions