Query on Ruby array


#1

Looking for suggestions on following two queries.

Query 1

Are the two following lines of code different in Ruby / Rails ( in a
*.html.erb) file.
<% if @forms.count != 0 %>
Vs.
<% if @forms.count %>

@forms is an array of objects. Coming from “C” language development
background, i thought they should be the same. FYI, second code
doesn’t give any error but still gets evaluated to TRUE. I confirmed
by doing puts @forms.count in controller

Query 2

which one is preferred
@forms. count or @forms.size
@forms is an array.

thanks
vipin


#2

On May 27, 9:35 am, Vipin removed_email_address@domain.invalid wrote:

@forms is an array of objects. Coming from “C” language development
background, i thought they should be the same. FYI, second code
doesn’t give any error but still gets evaluated to TRUE. I confirmed
by doing puts @forms.count in controller

They are different. in ruby, 0 has the logical value true (only nil
and false have the logical value false)

Query 2

which one is preferred
@forms. count or @forms.size
@forms is an array.

if forms is actually an array, forms.count doesn’t exist (but it does
if it is an association proxy, eg person.friends).

Fred


#3

On May 27, 1:42 pm, Frederick C. removed_email_address@domain.invalid
wrote:

<% if @forms.count %>

thanks
vipin

Thanks Fred.
so basically, I must use
<% if @forms.count != 0 %>

and about second point also, yes i got it through association only.
Also found that it doesn’t have count method.
I hope it is safe to use.


#4

On May 27, 9:44 am, Vipin removed_email_address@domain.invalid wrote:

Thanks Fred.
so basically, I must use
<% if @forms.count != 0 %>

@forms.any? is slightly more idiomatic ruby

and about second point also, yes i got it through association only.
Also found that it doesn’t have count method.

The big difference is that count always makes an sql query (select
count(*) … ) whereas if the association is already loaded size just
returns the length of the array.

Fred


#5

so basically, I must use
<% if @forms.count != 0 %>

@forms.any? is slightly more idiomatic ruby

<% if @forms.any? %>
is working and i believe it doesn’t have the penalty of SQL query
too.

thanks
vipin


#6

On 27/05/2009, at 7:32 PM, Vipin wrote:

@forms.count won’t work because @forms will most likely be an Array
object, and an Array doesn’t respond to count… it’ll respond to
size, tho…

@forms.size != 0

or you could do this

unless(@forms.blank?)

None of these will do a db connection because @forms contains objects
which have already been loaded (if they’re from the database).

Julian.


Learn: http://sensei.zenunit.com/
Last updated 20-May-09 (Rails, Basic Unix)
Blog: http://random8.zenunit.com/
Twitter: http://twitter.com/random8r


#7

On 27/05/2009, at 9:16 PM, Conrad T. wrote:

An Array instance can respond to both count and size methods. If
you use size the method with a counter
cache column on the has_many side, you can cache the total. For
example, you can do something
like this

Hi. Not sure where you got that from.

Loading development environment (Rails 2.3.2)

[].count
NoMethodError: undefined method `count’ for []:Array
from (irb):1

[].size
=> 0


Learn: http://sensei.zenunit.com/
Last updated 20-May-09 (Rails, Basic Unix)
Blog: http://random8.zenunit.com/
Twitter: http://twitter.com/random8r


#8

Conrad T. wrote:

An Array instance can respond to both count and size methods. If you
use
size the method with a counter
cache column on the has_many side, you can cache the total.

You can’t possibly mean an Array, because an Array doesn’t know anything
about going to databases or cacheing. An Array is just a list of stuff.

You might mean an ActiveRecord Association collection object, which
behaves a lot like an array, but also has some ‘magic’ ActiveRecord
behavior on it.

The fact that, as far as I know, there’s no actual class name for this
AR association magic collection object, makes things rather confusing, I
agree. I think it’s just some proxy methods singleton-added to an Array,
leaving us without a good name to call what it is, making things
confusing. Or if it really is a class, I don’t know what it’s called
cause it’s not mentioned in the docs. This is a kind of a-bit-too-clever
ruby hacking that Rails, IMHO, uses sometimes when it doesn’t really
have to, making things somewhat more confusing than they need to be.


#9

On Wed, May 27, 2009 at 3:08 AM, Julian L.
removed_email_address@domain.invalidwrote:

<% if @forms.any? %>
is working and i believe it doesn’t have the penalty of SQL query
too.

@forms.count won’t work because @forms will most likely be an Array
object, and an Array doesn’t respond to count… it’ll respond to
size, tho…

An Array instance can respond to both count and size methods. If you
use
size the method with a counter
cache column on the has_many side, you can cache the total. For
example,
you can do something
like this

class Post < ActiveRecord::Base

has_many :comments

end

class Comment < ActiveRecord::Base

belongs_to :post, :counter_cache => true

end

Note: You would add the counter cache column on the posts table like
this
using a migration:

      add_column :posts, :comments_count, :integer, :default => 0

Good luck,

-Conrad


#10

On Wed, May 27, 2009 at 5:31 AM, Julian L.
removed_email_address@domain.invalidwrote:

Hi. Not sure where you got that from.

Loading development environment (Rails 2.3.2)

[].count
NoMethodError: undefined method `count’ for []:Array
from (irb):1

[].size
=> 0

This statements are only true in Ruby prior to Ruby 1.8.6. For example,
in
Ruby 1.9.1, one can easily do the following:

irb(main):001:0> [].count
=> 0
irb(main):002:0> [].size
=> 0

-Conrad


#11

On Sat, May 30, 2009 at 11:05 AM, Conrad T. removed_email_address@domain.invalid
wrote:

This statements are only true in regards to Ruby 1.8.6. For example, in
Ruby 1.9.1, one can easily do the following:

irb(main):001:0> [].count
=> 0
irb(main):002:0> [].size
=> 0


#12

On May 30, 6:38 pm, Jonathan R. <rails-mailing-l…@andreas-
s.net> wrote:

behaves a lot like an array, but also has some ‘magic’ ActiveRecord
behavior on it.

The fact that, as far as I know, there’s no actual class name for this
AR association magic collection object, makes things rather confusing, I
agree. I think it’s just some proxy methods singleton-added to an Array,
leaving us without a good name to call what it is, making things
confusing. Or if it really is a class, I don’t know what it’s called
cause it’s not mentioned in the docs. This is a kind of a-bit-too-clever
ruby hacking that Rails, IMHO, uses sometimes when it doesn’t really
have to, making things somewhat more confusing than they need to be.

The classes in question are the various subclasses of
ActiveRecord::AssociationCollection (eg HasManyAssociation)

Fred


#13

On Sat, May 30, 2009 at 10:38 AM, Jonathan R. <
removed_email_address@domain.invalid> wrote:

You might mean an ActiveRecord Association collection object, which
have to, making things somewhat more confusing than they need to be.
In regards to a counter cache column, I’m referring to an
ActiveRecord::Base
association as I indicated in my example.

-Conrad