Rails 3: Difference between Relation.count and Relation.all.count -


moin,

i stumbled upon inconsistency in activerecord.
tried used combinations of values in 2 columns of large table. first idea:

select distinct col1, col2 table 

imagine rails app organizes meals model , each meal has_many :noodles each noodle has attributes (and hence db table columns) color , shape. goal number of present combinations of color , shape single meal.

since ar not provide "distinct" method used

my_meal.noodles.select("distinct color, shape") 

and got (in rails console stdout) 6 line output of 8 noodle objects (respectively string representations). but:

>> my_meal.noodles.select("distinct color, shape").count => 1606 

in fact my_meal contains 1606 noodles. if convert the relation array , size of or use .all.count result correct.

so question is, why ar output 8 objects count db lines?

a similar problem seems mentioned here no answer given.

thanks , best regards, tim

okay, tadman pushing me in right direction.

i digged deeper (especially in log files) , found little bit weird.

the problem caused number of selected columns. if 1 selects 1 column , counts result

my_meal.noodles.select("distinct color").count 

activerecord creates following sql statement:

select count(distinct color) count_id "noodles" ("noodles".meal_id = 295) 

in case 1 selects 2 or more columns , applies count it

my_meal.noodles.select("distinct color, shape").count 

activerecord forgets select clause , creates:

select count(*) count_id "noodles" ("noodles".meal_id = 295) 

this may right, since (sql's) count allows 1 or less columns parameters. add group before count , fine:

my_meal.noodles.select("distinct color, shape").group("color, shape").count  select count(*) count_all, color, shape color_shape "noodles" ("noodles".meal_id = 295) group color, shape 

apart as color_shape exact expected. but... returns this:

>> my_meal.noodles.select("distinct color, shape").group("color, shape").count => {star=>309, circle=>111, spaghetti=>189, square=>194, triangle=>179, bowtie=>301, shell=>93, letter=>230}  >> my_meal.noodles.select("distinct color, shape").group("color, shape").count.class => activesupport::orderedhash 

this weird return value (apart order depends on db) identical result , return value of

my_meal.noodles.group("shape").count 

conclusion:
pointed out here there still gap between relations (may mathematical or arel relations) , activerecord::relations.
can see advantages of pressing result in patterns of model possible (at least in context of rails app).
real relations not result of combination of several operations result of concatenation of operations. in general chainability of activerecord::relations great thing there design decisions cannot follow.
if can't depend on assurance each action returns new relation work with, looses of inuitional appeal.

as solution of problem, use above-mentioned group solution , kind of dirty workaround count operation:

my_meal.noodles.select("distinct color, shape").group("color, shape").all.count 

this compresses results acceptable minimum before pulling them out of database , creating expensive objects count them. alternatively 1 use handwritten sql query, why have rails , not use it, huh? ;-)

thanks help,
tim


Comments

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -