Strange behavior with has_many and size

Here is a “ruby script/console” session verbatim which will explain the
problem. Bear in mind that nothing is changing the database behind the
scenes at any time. topics is a has_many relationship of Sponsor.

s = Sponsor.find(3)
=> #<Sponsor:0x22fd804 @attributes={…

s.topics.size
=> 1

l = s.topics
=> [#<Topic:0x22d3fa4 @attributes={…

l.size
=> 20

s.topics.size
=> 20

Weird? Yes, but that’s the verbatim session.

It seems that s.topics.size and l.size should return the same number
(the correct number of related rows is 20). Why did s.topics.size
return the correct number the second time? When I put a tail on the
development log I can see the query that is being run and if I paste
that into a psql window, it (always) returns 20 rows. The query is
identical each time, it is just the value of size() that changes.

Unfortunately the same workaround does not work in application code. If,
in a view, I say this (assume a <% for sponsor in @sponsors %> outer
loop with @sponsors set in the controller):

<%= sponsor.topics.size %>

It shows up as 1 on the page, and if I do this:

<% l = sponsor.topics %>
<%= l.size %>
It still shows 1.

This is using Ruby 1.8.2 and locomotive on Mac Os X 10.4.4 with
PostgreSQL 7.4.
I hesitate to post more details of the tables or the has_many
relationship because it is proprietary stuff, but if anyone wants to
email me off-list I can provide more info.

Thanks
Dan
dan at dandante dot calm without the l

Dan T. wrote:

Here is a “ruby script/console” session verbatim which will explain the
problem…

I just tried the app on a linux system and it works fine. Something is
wrong with my installation on the Mac, but what?

Dan T. wrote:

Dan T. wrote:

Here is a “ruby script/console” session verbatim which will explain the
problem…

I just tried the app on a linux system and it works fine. Something is
wrong with my installation on the Mac, but what?

Sorry to keep replying to myself, but the problem occurs again on a
different linux box which is supposedly running the same versions of
everything as the linux box where everything works.

I’m very puzzled now…

Dan T. wrote:

Dan T. wrote:

Dan T. wrote:

Here is a “ruby script/console” session verbatim which will explain the
problem…

I just tried the app on a linux system and it works fine. Something is
wrong with my installation on the Mac, but what?

Sorry to keep replying to myself, but the problem occurs again on a
different linux box which is supposedly running the same versions of
everything as the linux box where everything works.

I’m very puzzled now…

What happens with this?

sponsor.topics.length

Or,

sponsor.topics.find(:all).size

Very strange indeed.

Dan T. wrote:

Chris S. wrote:

What happens with this?

sponsor.topics.length

That works! I had though that length() was just an alias to size() or
vice versa, now I see I’ll have to go back to the documentation and find
out the difference. Thanks!

Well, strangely, size is in the documentation as the correct way to
return the values. However, length works since you are getting back an
array. Just out of curiosity, do you have a counter_cache? Perhaps
that is being returned by the size method.

Or,

sponsor.topics.find(:all).size

That’s not valid syntax, apparently. But it doesn’t matter because
length() works.
Thanks again.

Hmm, I thought that worked… oh well :-p

Chris S. wrote:

What happens with this?

sponsor.topics.length

That works! I had though that length() was just an alias to size() or
vice versa, now I see I’ll have to go back to the documentation and find
out the difference. Thanks!

Or,

sponsor.topics.find(:all).size

That’s not valid syntax, apparently. But it doesn’t matter because
length() works.
Thanks again.